diff --git a/BBMOD_GML/BBMOD.resource_order b/BBMOD_GML/BBMOD.resource_order index 27c78d83..4150380a 100644 --- a/BBMOD_GML/BBMOD.resource_order +++ b/BBMOD_GML/BBMOD.resource_order @@ -16,8 +16,14 @@ {"name":"Model","order":4,"path":"folders/BBMOD/Core/Model.yy",}, {"name":"Properties","order":16,"path":"folders/BBMOD/Core/Properties.yy",}, {"name":"Rendering","order":8,"path":"folders/BBMOD/Core/Rendering.yy",}, + {"name":"Sprites","order":23,"path":"folders/BBMOD/Core/Sprites.yy",}, {"name":"Utils","order":9,"path":"folders/BBMOD/Core/Utils.yy",}, + {"name":"DeferredRenderer","order":16,"path":"folders/BBMOD/DeferredRenderer.yy",}, + {"name":"Shaders","order":1,"path":"folders/BBMOD/DeferredRenderer/Shaders.yy",}, + {"name":"Sprites","order":3,"path":"folders/BBMOD/DeferredRenderer/Sprites.yy",}, {"name":"Gizmo","order":11,"path":"folders/BBMOD/Gizmo.yy",}, + {"name":"Shaders","order":13,"path":"folders/BBMOD/Gizmo/Shaders.yy",}, + {"name":"Sprites","order":14,"path":"folders/BBMOD/Gizmo/Sprites.yy",}, {"name":"OBJImporter","order":2,"path":"folders/BBMOD/OBJImporter.yy",}, {"name":"Particles","order":13,"path":"folders/BBMOD/Particles.yy",}, {"name":"Modules","order":1,"path":"folders/BBMOD/Particles/Modules.yy",}, @@ -36,6 +42,8 @@ {"name":"MixPropertyOverTime","order":4,"path":"folders/BBMOD/Particles/Modules/Universal/MixPropertyOverTime.yy",}, {"name":"SetProperty","order":1,"path":"folders/BBMOD/Particles/Modules/Universal/SetProperty.yy",}, {"name":"Velocity","order":13,"path":"folders/BBMOD/Particles/Modules/Velocity.yy",}, + {"name":"Shaders","order":13,"path":"folders/BBMOD/Particles/Shaders.yy",}, + {"name":"Sprites","order":14,"path":"folders/BBMOD/Particles/Sprites.yy",}, {"name":"Raycasting","order":10,"path":"folders/BBMOD/Raycasting.yy",}, {"name":"Rendering","order":6,"path":"folders/BBMOD/Rendering.yy",}, {"name":"FXAA","order":5,"path":"folders/BBMOD/Rendering/FXAA.yy",}, @@ -45,6 +53,7 @@ {"name":"Save","order":15,"path":"folders/BBMOD/Save.yy",}, {"name":"StateMachine","order":5,"path":"folders/BBMOD/StateMachine.yy",}, {"name":"Terrain","order":8,"path":"folders/BBMOD/Terrain.yy",}, + {"name":"Shaders","order":8,"path":"folders/BBMOD/Terrain/Shaders.yy",}, {"name":"Fonts","order":7,"path":"folders/Demo/Fonts.yy",}, {"name":"Materials","order":5,"path":"folders/Demo/Materials.yy",}, {"name":"Objects","order":1,"path":"folders/Demo/Objects.yy",}, @@ -73,6 +82,7 @@ {"name":"BBMOD_State","order":1,"path":"scripts/BBMOD_State/BBMOD_State.yy",}, {"name":"BBMOD_ShSSAOBlur","order":2,"path":"shaders/BBMOD_ShSSAOBlur/BBMOD_ShSSAOBlur.yy",}, {"name":"BBMOD_PointLight","order":1,"path":"scripts/BBMOD_PointLight/BBMOD_PointLight.yy",}, + {"name":"__bbmod_deferred_material","order":2,"path":"scripts/__bbmod_deferred_material/__bbmod_deferred_material.yy",}, {"name":"BBMOD_ShDefaultAnimated","order":1,"path":"shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.yy",}, {"name":"BBMOD_Vec3","order":3,"path":"scripts/BBMOD_Vec3/BBMOD_Vec3.yy",}, {"name":"BBMOD_ShDefaultSprite","order":3,"path":"shaders/BBMOD_ShDefaultSprite/BBMOD_ShDefaultSprite.yy",}, @@ -80,7 +90,6 @@ {"name":"BBMOD_ShDefaultUnlitBatched","order":11,"path":"shaders/BBMOD_ShDefaultUnlitBatched/BBMOD_ShDefaultUnlitBatched.yy",}, {"name":"SprColorGrading","order":4,"path":"sprites/SprColorGrading/SprColorGrading.yy",}, {"name":"__bbmod_path","order":5,"path":"scripts/__bbmod_path/__bbmod_path.yy",}, - {"name":"BBMOD_ShExtractSplatmapLayer","order":1,"path":"shaders/BBMOD_ShExtractSplatmapLayer/BBMOD_ShExtractSplatmapLayer.yy",}, {"name":"SndGunshot1","order":1,"path":"sounds/SndGunshot1/SndGunshot1.yy",}, {"name":"BBMOD_CollisionKillModule","order":2,"path":"scripts/BBMOD_CollisionKillModule/BBMOD_CollisionKillModule.yy",}, {"name":"SndGunshot2","order":2,"path":"sounds/SndGunshot2/SndGunshot2.yy",}, @@ -89,7 +98,7 @@ {"name":"ODissolveEmitter","order":1,"path":"objects/ODissolveEmitter/ODissolveEmitter.yy",}, {"name":"SndShell4","order":4,"path":"sounds/SndShell4/SndShell4.yy",}, {"name":"__bbmod_async","order":3,"path":"scripts/__bbmod_async/__bbmod_async.yy",}, - {"name":"BBMOD_ShInstanceIDColor","order":10,"path":"shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.yy",}, + {"name":"BBMOD_ShInstanceIDColor","order":6,"path":"shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.yy",}, {"name":"bbmod_json_load","order":4,"path":"scripts/bbmod_json_load/bbmod_json_load.yy",}, {"name":"BBMOD_ParticleShader","order":12,"path":"scripts/BBMOD_ParticleShader/BBMOD_ParticleShader.yy",}, {"name":"__bbmod_sky","order":1,"path":"scripts/__bbmod_sky/__bbmod_sky.yy",}, @@ -100,32 +109,35 @@ {"name":"BBMOD_SetQuaternionModule","order":2,"path":"scripts/BBMOD_SetQuaternionModule/BBMOD_SetQuaternionModule.yy",}, {"name":"BBMOD_ShDefaultUnlitColor","order":13,"path":"shaders/BBMOD_ShDefaultUnlitColor/BBMOD_ShDefaultUnlitColor.yy",}, {"name":"SndShell2","order":2,"path":"sounds/SndShell2/SndShell2.yy",}, + {"name":"bbmod_hdr_is_supported","order":20,"path":"scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.yy",}, {"name":"SndShell5","order":5,"path":"sounds/SndShell5/SndShell5.yy",}, - {"name":"BBMOD_ShInstanceIDColorBatched","order":11,"path":"shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy",}, + {"name":"BBMOD_ShInstanceIDColorBatched","order":8,"path":"shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy",}, {"name":"__bbmod_camera","order":12,"path":"scripts/__bbmod_camera/__bbmod_camera.yy",}, {"name":"BBMOD_MixVec2FromSpeedModule","order":3,"path":"scripts/BBMOD_MixVec2FromSpeedModule/BBMOD_MixVec2FromSpeedModule.yy",}, {"name":"BBMOD_ShDefaultDepthLightmap","order":5,"path":"shaders/BBMOD_ShDefaultDepthLightmap/BBMOD_ShDefaultDepthLightmap.yy",}, {"name":"BBMOD_CameraHTML5","order":1,"path":"extensions/BBMOD_CameraHTML5/BBMOD_CameraHTML5.yy",}, {"name":"BBMOD_AnimationState","order":3,"path":"scripts/BBMOD_AnimationState/BBMOD_AnimationState.yy",}, - {"name":"__BBMOD_ShCheckVTF","order":7,"path":"shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.yy",}, + {"name":"BBMOD_ShCheckVTF","order":7,"path":"shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.yy",}, {"name":"OPlayer","order":1,"path":"objects/OPlayer/OPlayer.yy",}, {"name":"SndFootstep4","order":4,"path":"sounds/SndFootstep4/SndFootstep4.yy",}, {"name":"RmGameOver","order":1,"path":"rooms/RmGameOver/RmGameOver.yy",}, {"name":"__bbmod_vertex_buffer","order":16,"path":"scripts/__bbmod_vertex_buffer/__bbmod_vertex_buffer.yy",}, + {"name":"BBMOD_ShGBufferExtractA","order":10,"path":"shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.yy",}, {"name":"DissolveParticleSystem","order":1,"path":"scripts/DissolveParticleSystem/DissolveParticleSystem.yy",}, {"name":"bbmod_set_instance_id","order":10,"path":"scripts/bbmod_set_instance_id/bbmod_set_instance_id.yy",}, - {"name":"BBMOD_ShInstanceIDAnimated","order":1,"path":"shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy",}, + {"name":"BBMOD_ShInstanceIDAnimated","order":4,"path":"shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy",}, {"name":"BBMOD_VertexFormat","order":4,"path":"scripts/BBMOD_VertexFormat/BBMOD_VertexFormat.yy",}, {"name":"BBMOD_LightmapShader","order":1,"path":"scripts/BBMOD_LightmapShader/BBMOD_LightmapShader.yy",}, {"name":"BBMOD_IRenderable","order":1,"path":"scripts/BBMOD_IRenderable/BBMOD_IRenderable.yy",}, {"name":"BBMOD_MixQuaternionFromSpeedModule","order":1,"path":"scripts/BBMOD_MixQuaternionFromSpeedModule/BBMOD_MixQuaternionFromSpeedModule.yy",}, {"name":"BBMOD_MixVec2OverTimeModule","order":3,"path":"scripts/BBMOD_MixVec2OverTimeModule/BBMOD_MixVec2OverTimeModule.yy",}, {"name":"__bbmod_fog","order":11,"path":"scripts/__bbmod_fog/__bbmod_fog.yy",}, + {"name":"BBMOD_ShDeferredPunctual","order":11,"path":"shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.yy",}, {"name":"BBMOD_ParticleSystem","order":6,"path":"scripts/BBMOD_ParticleSystem/BBMOD_ParticleSystem.yy",}, {"name":"BBMOD_MaterialPropertyBlock","order":17,"path":"scripts/BBMOD_MaterialPropertyBlock/BBMOD_MaterialPropertyBlock.yy",}, - {"name":"BBMOD_ShGizmo","order":7,"path":"shaders/BBMOD_ShGizmo/BBMOD_ShGizmo.yy",}, {"name":"BBMOD_ShDefaultUnlit","order":10,"path":"shaders/BBMOD_ShDefaultUnlit/BBMOD_ShDefaultUnlit.yy",}, - {"name":"__BBMOD_ShCubemapToOctahedron","order":15,"path":"shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.yy",}, + {"name":"BBMOD_ShGBufferTerrain","order":3,"path":"shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.yy",}, + {"name":"BBMOD_ShCubemapToOctahedron","order":15,"path":"shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.yy",}, {"name":"BBMOD_MixQuaternionModule","order":5,"path":"scripts/BBMOD_MixQuaternionModule/BBMOD_MixQuaternionModule.yy",}, {"name":"BBMOD_RenderQueue","order":6,"path":"scripts/BBMOD_RenderQueue/BBMOD_RenderQueue.yy",}, {"name":"BBMOD_MixRealFromSpeedModule","order":2,"path":"scripts/BBMOD_MixRealFromSpeedModule/BBMOD_MixRealFromSpeedModule.yy",}, @@ -144,14 +156,16 @@ {"name":"BBMOD_ERenderCommand","order":8,"path":"scripts/BBMOD_ERenderCommand/BBMOD_ERenderCommand.yy",}, {"name":"BBMOD_EmissionModule","order":1,"path":"scripts/BBMOD_EmissionModule/BBMOD_EmissionModule.yy",}, {"name":"BBMOD_ShDefaultColorBatched","order":17,"path":"shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.yy",}, - {"name":"__BBMOD_ShPrefilterDiffuse","order":17,"path":"shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.yy",}, + {"name":"BBMOD_ShInstanceID","order":3,"path":"shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.yy",}, + {"name":"BBMOD_ShPrefilterDiffuse","order":17,"path":"shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.yy",}, {"name":"OItem","order":1,"path":"objects/OItem/OItem.yy",}, {"name":"SndWhoosh","order":5,"path":"sounds/SndWhoosh/SndWhoosh.yy",}, + {"name":"BBMOD_ShGBufferColor","order":4,"path":"shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.yy",}, {"name":"BBMOD_AddVec2OverTimeModule","order":3,"path":"scripts/BBMOD_AddVec2OverTimeModule/BBMOD_AddVec2OverTimeModule.yy",}, {"name":"SprSplatmap","order":3,"path":"sprites/SprSplatmap/SprSplatmap.yy",}, {"name":"__bbmod_d3d11","order":9,"path":"scripts/__bbmod_d3d11/__bbmod_d3d11.yy",}, {"name":"BBMOD_MixVec2FromHealthModule","order":2,"path":"scripts/BBMOD_MixVec2FromHealthModule/BBMOD_MixVec2FromHealthModule.yy",}, - {"name":"__BBMOD_ShCheckMRT","order":11,"path":"shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.yy",}, + {"name":"BBMOD_ShCheckMRT","order":11,"path":"shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.yy",}, {"name":"BBMOD_AddVec3OverTimeModule","order":2,"path":"scripts/BBMOD_AddVec3OverTimeModule/BBMOD_AddVec3OverTimeModule.yy",}, {"name":"BBMOD_EParticle","order":3,"path":"scripts/BBMOD_EParticle/BBMOD_EParticle.yy",}, {"name":"bbmod_surface_check","order":2,"path":"scripts/bbmod_surface_check/bbmod_surface_check.yy",}, @@ -173,28 +187,31 @@ {"name":"SndFootstep9","order":9,"path":"sounds/SndFootstep9/SndFootstep9.yy",}, {"name":"SndFootstep5","order":5,"path":"sounds/SndFootstep5/SndFootstep5.yy",}, {"name":"BBMOD_Resource","order":12,"path":"scripts/BBMOD_Resource/BBMOD_Resource.yy",}, + {"name":"BBMOD_ShGBufferColorBatched","order":6,"path":"shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.yy",}, {"name":"OZombie","order":2,"path":"objects/OZombie/OZombie.yy",}, {"name":"SndShell3","order":3,"path":"sounds/SndShell3/SndShell3.yy",}, {"name":"BBMOD_SprDefaultSpecularColor","order":2,"path":"sprites/BBMOD_SprDefaultSpecularColor/BBMOD_SprDefaultSpecularColor.yy",}, + {"name":"BBMOD_ShGBufferExtractRGB","order":9,"path":"shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.yy",}, {"name":"BBMOD_AddVec3OnCollisionModule","order":2,"path":"scripts/BBMOD_AddVec3OnCollisionModule/BBMOD_AddVec3OnCollisionModule.yy",}, {"name":"BBMOD_EAntialiasing","order":3,"path":"scripts/BBMOD_EAntialiasing/BBMOD_EAntialiasing.yy",}, {"name":"BBMOD_MixVec4FromHealthModule","order":4,"path":"scripts/BBMOD_MixVec4FromHealthModule/BBMOD_MixVec4FromHealthModule.yy",}, {"name":"BBMOD_NotImplementedException","order":1,"path":"scripts/BBMOD_NotImplementedException/BBMOD_NotImplementedException.yy",}, {"name":"BBMOD_ParticleModule","order":5,"path":"scripts/BBMOD_ParticleModule/BBMOD_ParticleModule.yy",}, {"name":"BBMOD_SetVec3Module","order":4,"path":"scripts/BBMOD_SetVec3Module/BBMOD_SetVec3Module.yy",}, - {"name":"BBMOD_ShTerrain","order":3,"path":"shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.yy",}, + {"name":"BBMOD_ShTerrain","order":1,"path":"shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.yy",}, {"name":"BBMOD_ShDefaultColorAnimated","order":18,"path":"shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.yy",}, {"name":"ShZombieDepth","order":1,"path":"shaders/ShZombieDepth/ShZombieDepth.yy",}, + {"name":"__bbmod_matrix_proj_get_tanaspect","order":19,"path":"scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.yy",}, {"name":"BBMOD_TerrainLayer","order":5,"path":"scripts/BBMOD_TerrainLayer/BBMOD_TerrainLayer.yy",}, - {"name":"__BBMOD_ShPrefilterSpecular","order":16,"path":"shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.yy",}, + {"name":"BBMOD_ShPrefilterSpecular","order":16,"path":"shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.yy",}, {"name":"BBMOD_SpotLight","order":4,"path":"scripts/BBMOD_SpotLight/BBMOD_SpotLight.yy",}, {"name":"BBMOD_DefaultLightmapMaterial","order":6,"path":"scripts/BBMOD_DefaultLightmapMaterial/BBMOD_DefaultLightmapMaterial.yy",}, {"name":"bbmod_lerp_delta_time","order":5,"path":"scripts/bbmod_lerp_delta_time/bbmod_lerp_delta_time.yy",}, {"name":"BBMOD_PunctualLight","order":6,"path":"scripts/BBMOD_PunctualLight/BBMOD_PunctualLight.yy",}, - {"name":"BBMOD_SprWhite","order":15,"path":"sprites/BBMOD_SprWhite/BBMOD_SprWhite.yy",}, + {"name":"BBMOD_SprWhite","order":2,"path":"sprites/BBMOD_SprWhite/BBMOD_SprWhite.yy",}, {"name":"BBMOD_OBJImporter","order":2,"path":"scripts/BBMOD_OBJImporter/BBMOD_OBJImporter.yy",}, {"name":"RmInit","order":2,"path":"rooms/RmInit/RmInit.yy",}, - {"name":"BBMOD_ShParticleUnlit","order":9,"path":"shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.yy",}, + {"name":"BBMOD_ShParticleUnlit","order":2,"path":"shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.yy",}, {"name":"BBMOD_ParticleMaterial","order":11,"path":"scripts/BBMOD_ParticleMaterial/BBMOD_ParticleMaterial.yy",}, {"name":"SndShell6","order":6,"path":"sounds/SndShell6/SndShell6.yy",}, {"name":"BBMOD_SprDefaultNormalW","order":1,"path":"sprites/BBMOD_SprDefaultNormalW/BBMOD_SprDefaultNormalW.yy",}, @@ -208,16 +225,17 @@ {"name":"BBMOD_TerrainShader","order":6,"path":"scripts/BBMOD_TerrainShader/BBMOD_TerrainShader.yy",}, {"name":"BBMOD_MixSpeedModule","order":1,"path":"scripts/BBMOD_MixSpeedModule/BBMOD_MixSpeedModule.yy",}, {"name":"BBMOD_Matrix","order":6,"path":"scripts/BBMOD_Matrix/BBMOD_Matrix.yy",}, - {"name":"BBMOD_SprBlack","order":14,"path":"sprites/BBMOD_SprBlack/BBMOD_SprBlack.yy",}, {"name":"BBMOD_AddVec2OnCollisionModule","order":1,"path":"scripts/BBMOD_AddVec2OnCollisionModule/BBMOD_AddVec2OnCollisionModule.yy",}, {"name":"BBMOD_OutOfRangeException","order":2,"path":"scripts/BBMOD_OutOfRangeException/BBMOD_OutOfRangeException.yy",}, {"name":"BBMOD_AddVec4OverTimeModule","order":1,"path":"scripts/BBMOD_AddVec4OverTimeModule/BBMOD_AddVec4OverTimeModule.yy",}, {"name":"BBMOD_Vec4","order":4,"path":"scripts/BBMOD_Vec4/BBMOD_Vec4.yy",}, {"name":"SndFootstep1","order":1,"path":"sounds/SndFootstep1/SndFootstep1.yy",}, {"name":"SprHeightmap","order":2,"path":"sprites/SprHeightmap/SprHeightmap.yy",}, - {"name":"BBMOD_ShGizmoSelect","order":5,"path":"shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy",}, + {"name":"BBMOD_ShGizmoSelect","order":1,"path":"shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy",}, {"name":"BBMOD_MixVec3FromHealthModule","order":3,"path":"scripts/BBMOD_MixVec3FromHealthModule/BBMOD_MixVec3FromHealthModule.yy",}, + {"name":"BBMOD_ShGBufferColorAnimated","order":5,"path":"shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.yy",}, {"name":"BBMOD_ShDefaultDepth","order":7,"path":"shaders/BBMOD_ShDefaultDepth/BBMOD_ShDefaultDepth.yy",}, + {"name":"BBMOD_ShDeferredFullscreen","order":7,"path":"shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.yy",}, {"name":"BBMOD_ShDefaultLightmap","order":4,"path":"shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.yy",}, {"name":"bbmod_mrt_is_supported","order":12,"path":"scripts/bbmod_mrt_is_supported/bbmod_mrt_is_supported.yy",}, {"name":"BBMOD_Collider","order":2,"path":"scripts/BBMOD_Collider/BBMOD_Collider.yy",}, @@ -233,8 +251,10 @@ {"name":"BBMOD_DragModule","order":1,"path":"scripts/BBMOD_DragModule/BBMOD_DragModule.yy",}, {"name":"BBMOD_MixVec4OverTimeModule","order":5,"path":"scripts/BBMOD_MixVec4OverTimeModule/BBMOD_MixVec4OverTimeModule.yy",}, {"name":"BBMOD_AnimationPlayer","order":4,"path":"scripts/BBMOD_AnimationPlayer/BBMOD_AnimationPlayer.yy",}, + {"name":"BBMOD_ShFogAndDepthMask","order":13,"path":"shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.yy",}, {"name":"__bbmod_logging","order":10,"path":"scripts/__bbmod_logging/__bbmod_logging.yy",}, {"name":"OFloatingText","order":1,"path":"objects/OFloatingText/OFloatingText.yy",}, + {"name":"BBMOD_ShGBufferAnimated","order":1,"path":"shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.yy",}, {"name":"BBMOD_AnimationStateMachine","order":2,"path":"scripts/BBMOD_AnimationStateMachine/BBMOD_AnimationStateMachine.yy",}, {"name":"BBMOD_AnimationInstance","order":1,"path":"scripts/BBMOD_AnimationInstance/BBMOD_AnimationInstance.yy",}, {"name":"BBMOD_SetVec2Module","order":3,"path":"scripts/BBMOD_SetVec2Module/BBMOD_SetVec2Module.yy",}, @@ -243,13 +263,11 @@ {"name":"BBMOD_DefaultSpriteShader","order":9,"path":"scripts/BBMOD_DefaultSpriteShader/BBMOD_DefaultSpriteShader.yy",}, {"name":"BBMOD_MixRealOverTimeModule","order":2,"path":"scripts/BBMOD_MixRealOverTimeModule/BBMOD_MixRealOverTimeModule.yy",}, {"name":"BBMOD_IMeshRenderQueue","order":4,"path":"scripts/BBMOD_IMeshRenderQueue/BBMOD_IMeshRenderQueue.yy",}, - {"name":"BBMOD_SprParticle","order":10,"path":"sprites/BBMOD_SprParticle/BBMOD_SprParticle.yy",}, {"name":"bbmod_get_calling_function_name","order":1,"path":"scripts/bbmod_get_calling_function_name/bbmod_get_calling_function_name.yy",}, {"name":"SndGunshot3","order":3,"path":"sounds/SndGunshot3/SndGunshot3.yy",}, {"name":"BBMOD_GravityModule","order":2,"path":"scripts/BBMOD_GravityModule/BBMOD_GravityModule.yy",}, {"name":"OGameOver","order":7,"path":"objects/OGameOver/OGameOver.yy",}, {"name":"__bbmod_mipmapping","order":17,"path":"scripts/__bbmod_mipmapping/__bbmod_mipmapping.yy",}, - {"name":"BBMOD_SprGizmo","order":4,"path":"sprites/BBMOD_SprGizmo/BBMOD_SprGizmo.yy",}, {"name":"BBMOD_IDestructible","order":3,"path":"scripts/BBMOD_IDestructible/BBMOD_IDestructible.yy",}, {"name":"BBMOD_ShDefaultDepthColorAnimated","order":21,"path":"shaders/BBMOD_ShDefaultDepthColorAnimated/BBMOD_ShDefaultDepthColorAnimated.yy",}, {"name":"BBMOD_SetRealModule","order":1,"path":"scripts/BBMOD_SetRealModule/BBMOD_SetRealModule.yy",}, @@ -258,15 +276,15 @@ {"name":"BBMOD_MixVec3OverTimeModule","order":4,"path":"scripts/BBMOD_MixVec3OverTimeModule/BBMOD_MixVec3OverTimeModule.yy",}, {"name":"BBMOD_AddVec4OnCollisionModule","order":3,"path":"scripts/BBMOD_AddVec4OnCollisionModule/BBMOD_AddVec4OnCollisionModule.yy",}, {"name":"__bbmod_render_pass","order":1,"path":"scripts/__bbmod_render_pass/__bbmod_render_pass.yy",}, - {"name":"BBMOD_ShParticleDepth","order":7,"path":"shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.yy",}, {"name":"BBMOD_MixColorModule","order":4,"path":"scripts/BBMOD_MixColorModule/BBMOD_MixColorModule.yy",}, + {"name":"__bbmod_shader_set","order":21,"path":"scripts/__bbmod_shader_set/__bbmod_shader_set.yy",}, {"name":"MatZombie","order":1,"path":"scripts/MatZombie/MatZombie.yy",}, {"name":"__bbmod_blendmode","order":14,"path":"scripts/__bbmod_blendmode/__bbmod_blendmode.yy",}, {"name":"BBMOD_ParticleEmitter","order":4,"path":"scripts/BBMOD_ParticleEmitter/BBMOD_ParticleEmitter.yy",}, - {"name":"BBMOD_ShInstanceHighlight","order":6,"path":"shaders/BBMOD_ShInstanceHighlight/BBMOD_ShInstanceHighlight.yy",}, + {"name":"BBMOD_ShInstanceHighlight","order":2,"path":"shaders/BBMOD_ShInstanceHighlight/BBMOD_ShInstanceHighlight.yy",}, {"name":"bbmod_cmp","order":1,"path":"scripts/bbmod_cmp/bbmod_cmp.yy",}, {"name":"Fnt48","order":2,"path":"fonts/Fnt48/Fnt48.yy",}, - {"name":"BBMOD_ShTerrainUnlit","order":4,"path":"shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.yy",}, + {"name":"BBMOD_ShTerrainUnlit","order":2,"path":"shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.yy",}, {"name":"SprDirt","order":1,"path":"sprites/SprDirt/SprDirt.yy",}, {"name":"BBMOD_ShDefaultUnlitColorBatched","order":14,"path":"shaders/BBMOD_ShDefaultUnlitColorBatched/BBMOD_ShDefaultUnlitColorBatched.yy",}, {"name":"BBMOD_ResourceManager","order":18,"path":"scripts/BBMOD_ResourceManager/BBMOD_ResourceManager.yy",}, @@ -277,23 +295,25 @@ {"name":"bbmod_gpu_get_default_state","order":9,"path":"scripts/bbmod_gpu_get_default_state/bbmod_gpu_get_default_state.yy",}, {"name":"BBMOD_DefaultLightmapShader","order":7,"path":"scripts/BBMOD_DefaultLightmapShader/BBMOD_DefaultLightmapShader.yy",}, {"name":"SndFootstep3","order":3,"path":"sounds/SndFootstep3/SndFootstep3.yy",}, - {"name":"BBMOD_ShInstanceIDColorAnimated","order":12,"path":"shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.yy",}, + {"name":"BBMOD_ShInstanceIDColorAnimated","order":7,"path":"shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.yy",}, {"name":"__bbmod_particles","order":2,"path":"scripts/__bbmod_particles/__bbmod_particles.yy",}, {"name":"BBMOD_BaseCamera","order":2,"path":"scripts/BBMOD_BaseCamera/BBMOD_BaseCamera.yy",}, {"name":"BBMOD_MixQuaternionFromHealthModule","order":5,"path":"scripts/BBMOD_MixQuaternionFromHealthModule/BBMOD_MixQuaternionFromHealthModule.yy",}, - {"name":"BBMOD_ShParticleLit","order":8,"path":"shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.yy",}, + {"name":"BBMOD_ShParticleLit","order":1,"path":"shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.yy",}, {"name":"BBMOD_PlaneCollider","order":3,"path":"scripts/BBMOD_PlaneCollider/BBMOD_PlaneCollider.yy",}, {"name":"BBMOD_MixEmissionModule","order":2,"path":"scripts/BBMOD_MixEmissionModule/BBMOD_MixEmissionModule.yy",}, {"name":"SndShell7","order":7,"path":"sounds/SndShell7/SndShell7.yy",}, {"name":"BBMOD_MixQuaternionOverTimeModule","order":1,"path":"scripts/BBMOD_MixQuaternionOverTimeModule/BBMOD_MixQuaternionOverTimeModule.yy",}, - {"name":"__BBMOD_ShMixRGBM","order":19,"path":"shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.yy",}, + {"name":"BBMOD_ShMixRGBM","order":19,"path":"shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.yy",}, {"name":"OGunfireEmitter","order":6,"path":"objects/OGunfireEmitter/OGunfireEmitter.yy",}, - {"name":"BBMOD_ShInstanceIDBatched","order":8,"path":"shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy",}, + {"name":"BBMOD_ShInstanceIDBatched","order":5,"path":"shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy",}, + {"name":"BBMOD_ShGBufferBatched","order":2,"path":"shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.yy",}, {"name":"OSky","order":2,"path":"objects/OSky/OSky.yy",}, {"name":"BBMOD_MixVec2Module","order":3,"path":"scripts/BBMOD_MixVec2Module/BBMOD_MixVec2Module.yy",}, {"name":"BBMOD_BaseRenderer","order":14,"path":"scripts/BBMOD_BaseRenderer/BBMOD_BaseRenderer.yy",}, {"name":"SndShell1","order":1,"path":"sounds/SndShell1/SndShell1.yy",}, - {"name":"BBMOD_SprCheckerboard","order":22,"path":"sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy",}, + {"name":"BBMOD_SprCheckerboard","order":1,"path":"sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy",}, + {"name":"ShZombieGBuffer","order":2,"path":"shaders/ShZombieGBuffer/ShZombieGBuffer.yy",}, {"name":"GunfireParticleSystem","order":2,"path":"scripts/GunfireParticleSystem/GunfireParticleSystem.yy",}, {"name":"BBMOD_Shader","order":4,"path":"scripts/BBMOD_Shader/BBMOD_Shader.yy",}, {"name":"BBMOD_ShDefaultDepthColorBatched","order":20,"path":"shaders/BBMOD_ShDefaultDepthColorBatched/BBMOD_ShDefaultDepthColorBatched.yy",}, @@ -303,6 +323,7 @@ {"name":"BBMOD_ShInstanceIDLightmap","order":9,"path":"shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.yy",}, {"name":"SndGunshot4","order":4,"path":"sounds/SndGunshot4/SndGunshot4.yy",}, {"name":"BBMOD_ShDefaultDepthBatched","order":9,"path":"shaders/BBMOD_ShDefaultDepthBatched/BBMOD_ShDefaultDepthBatched.yy",}, + {"name":"BBMOD_ShHDRToSDR","order":12,"path":"shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.yy",}, {"name":"BBMOD_ReflectionProbe","order":18,"path":"scripts/BBMOD_ReflectionProbe/BBMOD_ReflectionProbe.yy",}, {"name":"BBMOD_RaycastResult","order":5,"path":"scripts/BBMOD_RaycastResult/BBMOD_RaycastResult.yy",}, {"name":"__bbmod_default_material","order":1,"path":"scripts/__bbmod_default_material/__bbmod_default_material.yy",}, diff --git a/BBMOD_GML/BBMOD.yyp b/BBMOD_GML/BBMOD.yyp index c81d0d44..66d7032a 100644 --- a/BBMOD_GML/BBMOD.yyp +++ b/BBMOD_GML/BBMOD.yyp @@ -29,8 +29,14 @@ {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Model","folderPath":"folders/BBMOD/Core/Model.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Properties","folderPath":"folders/BBMOD/Core/Properties.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Rendering","folderPath":"folders/BBMOD/Core/Rendering.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Sprites","folderPath":"folders/BBMOD/Core/Sprites.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Utils","folderPath":"folders/BBMOD/Core/Utils.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"DeferredRenderer","folderPath":"folders/BBMOD/DeferredRenderer.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Shaders","folderPath":"folders/BBMOD/DeferredRenderer/Shaders.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Sprites","folderPath":"folders/BBMOD/DeferredRenderer/Sprites.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Gizmo","folderPath":"folders/BBMOD/Gizmo.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Shaders","folderPath":"folders/BBMOD/Gizmo/Shaders.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Sprites","folderPath":"folders/BBMOD/Gizmo/Sprites.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"OBJImporter","folderPath":"folders/BBMOD/OBJImporter.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Particles","folderPath":"folders/BBMOD/Particles.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Modules","folderPath":"folders/BBMOD/Particles/Modules.yy",}, @@ -50,6 +56,8 @@ {"resourceType":"GMFolder","resourceVersion":"1.0","name":"MixPropertyOverTime","folderPath":"folders/BBMOD/Particles/Modules/Universal/MixPropertyOverTime.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"SetProperty","folderPath":"folders/BBMOD/Particles/Modules/Universal/SetProperty.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Velocity","folderPath":"folders/BBMOD/Particles/Modules/Velocity.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Shaders","folderPath":"folders/BBMOD/Particles/Shaders.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Sprites","folderPath":"folders/BBMOD/Particles/Sprites.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Raycasting","folderPath":"folders/BBMOD/Raycasting.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Rendering","folderPath":"folders/BBMOD/Rendering.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"FXAA","folderPath":"folders/BBMOD/Rendering/FXAA.yy",}, @@ -59,6 +67,7 @@ {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Save","folderPath":"folders/BBMOD/Save.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"StateMachine","folderPath":"folders/BBMOD/StateMachine.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Terrain","folderPath":"folders/BBMOD/Terrain.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Shaders","folderPath":"folders/BBMOD/Terrain/Shaders.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Demo","folderPath":"folders/Demo.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Fonts","folderPath":"folders/Demo/Fonts.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Materials","folderPath":"folders/Demo/Materials.yy",}, @@ -145,6 +154,7 @@ "IDEVersion": "2023.800.0.406", }, "resources": [ + {"id":{"name":"BBMOD_DeferredRenderer","path":"scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.yy",},}, {"id":{"name":"BBMOD_ShDefaultColor","path":"shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.yy",},}, {"id":{"name":"BBMOD_Cubemap","path":"scripts/BBMOD_Cubemap/BBMOD_Cubemap.yy",},}, {"id":{"name":"BBMOD_PostProcessor","path":"scripts/BBMOD_PostProcessor/BBMOD_PostProcessor.yy",},}, @@ -155,6 +165,7 @@ {"id":{"name":"BBMOD_State","path":"scripts/BBMOD_State/BBMOD_State.yy",},}, {"id":{"name":"BBMOD_ShSSAOBlur","path":"shaders/BBMOD_ShSSAOBlur/BBMOD_ShSSAOBlur.yy",},}, {"id":{"name":"BBMOD_PointLight","path":"scripts/BBMOD_PointLight/BBMOD_PointLight.yy",},}, + {"id":{"name":"__bbmod_deferred_material","path":"scripts/__bbmod_deferred_material/__bbmod_deferred_material.yy",},}, {"id":{"name":"BBMOD_ShDefaultAnimated","path":"shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.yy",},}, {"id":{"name":"BBMOD_Vec3","path":"scripts/BBMOD_Vec3/BBMOD_Vec3.yy",},}, {"id":{"name":"BBMOD_ShDefaultSprite","path":"shaders/BBMOD_ShDefaultSprite/BBMOD_ShDefaultSprite.yy",},}, @@ -187,19 +198,22 @@ {"id":{"name":"BBMOD_ShDefaultUnlitColor","path":"shaders/BBMOD_ShDefaultUnlitColor/BBMOD_ShDefaultUnlitColor.yy",},}, {"id":{"name":"SndShell2","path":"sounds/SndShell2/SndShell2.yy",},}, {"id":{"name":"RmDemo","path":"rooms/RmDemo/RmDemo.yy",},}, + {"id":{"name":"bbmod_hdr_is_supported","path":"scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.yy",},}, {"id":{"name":"SndShell5","path":"sounds/SndShell5/SndShell5.yy",},}, {"id":{"name":"BBMOD_ShInstanceIDColorBatched","path":"shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy",},}, + {"id":{"name":"BBMOD_ShGBuffer","path":"shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.yy",},}, {"id":{"name":"__bbmod_camera","path":"scripts/__bbmod_camera/__bbmod_camera.yy",},}, {"id":{"name":"BBMOD_MixVec2FromSpeedModule","path":"scripts/BBMOD_MixVec2FromSpeedModule/BBMOD_MixVec2FromSpeedModule.yy",},}, {"id":{"name":"BBMOD_ShDefaultDepthLightmap","path":"shaders/BBMOD_ShDefaultDepthLightmap/BBMOD_ShDefaultDepthLightmap.yy",},}, {"id":{"name":"BBMOD_CameraHTML5","path":"extensions/BBMOD_CameraHTML5/BBMOD_CameraHTML5.yy",},}, {"id":{"name":"BBMOD_AnimationState","path":"scripts/BBMOD_AnimationState/BBMOD_AnimationState.yy",},}, - {"id":{"name":"__BBMOD_ShCheckVTF","path":"shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.yy",},}, + {"id":{"name":"BBMOD_ShCheckVTF","path":"shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.yy",},}, {"id":{"name":"BBMOD_CollisionEventModule","path":"scripts/BBMOD_CollisionEventModule/BBMOD_CollisionEventModule.yy",},}, {"id":{"name":"OPlayer","path":"objects/OPlayer/OPlayer.yy",},}, {"id":{"name":"SndFootstep4","path":"sounds/SndFootstep4/SndFootstep4.yy",},}, {"id":{"name":"RmGameOver","path":"rooms/RmGameOver/RmGameOver.yy",},}, {"id":{"name":"__bbmod_vertex_buffer","path":"scripts/__bbmod_vertex_buffer/__bbmod_vertex_buffer.yy",},}, + {"id":{"name":"BBMOD_ShGBufferExtractA","path":"shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.yy",},}, {"id":{"name":"DissolveParticleSystem","path":"scripts/DissolveParticleSystem/DissolveParticleSystem.yy",},}, {"id":{"name":"bbmod_set_instance_id","path":"scripts/bbmod_set_instance_id/bbmod_set_instance_id.yy",},}, {"id":{"name":"BBMOD_ShInstanceIDAnimated","path":"shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy",},}, @@ -212,12 +226,15 @@ {"id":{"name":"BBMOD_MixVec2OverTimeModule","path":"scripts/BBMOD_MixVec2OverTimeModule/BBMOD_MixVec2OverTimeModule.yy",},}, {"id":{"name":"BBMOD_MixColorFromHealthModule","path":"scripts/BBMOD_MixColorFromHealthModule/BBMOD_MixColorFromHealthModule.yy",},}, {"id":{"name":"__bbmod_fog","path":"scripts/__bbmod_fog/__bbmod_fog.yy",},}, + {"id":{"name":"BBMOD_ShDeferredPunctual","path":"shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.yy",},}, {"id":{"name":"BBMOD_ParticleSystem","path":"scripts/BBMOD_ParticleSystem/BBMOD_ParticleSystem.yy",},}, {"id":{"name":"BBMOD_MaterialPropertyBlock","path":"scripts/BBMOD_MaterialPropertyBlock/BBMOD_MaterialPropertyBlock.yy",},}, + {"id":{"name":"BBMOD_SprBestFitNormalLUT","path":"sprites/BBMOD_SprBestFitNormalLUT/BBMOD_SprBestFitNormalLUT.yy",},}, {"id":{"name":"BBMOD_ShGizmo","path":"shaders/BBMOD_ShGizmo/BBMOD_ShGizmo.yy",},}, {"id":{"name":"BBMOD_ShDefaultUnlit","path":"shaders/BBMOD_ShDefaultUnlit/BBMOD_ShDefaultUnlit.yy",},}, {"id":{"name":"BBMOD_Animation","path":"scripts/BBMOD_Animation/BBMOD_Animation.yy",},}, - {"id":{"name":"__BBMOD_ShCubemapToOctahedron","path":"shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.yy",},}, + {"id":{"name":"BBMOD_ShGBufferTerrain","path":"shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.yy",},}, + {"id":{"name":"BBMOD_ShCubemapToOctahedron","path":"shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.yy",},}, {"id":{"name":"BBMOD_LightmapMaterial","path":"scripts/BBMOD_LightmapMaterial/BBMOD_LightmapMaterial.yy",},}, {"id":{"name":"BBMOD_MixQuaternionModule","path":"scripts/BBMOD_MixQuaternionModule/BBMOD_MixQuaternionModule.yy",},}, {"id":{"name":"BBMOD_RenderQueue","path":"scripts/BBMOD_RenderQueue/BBMOD_RenderQueue.yy",},}, @@ -243,15 +260,16 @@ {"id":{"name":"BBMOD_EmissionModule","path":"scripts/BBMOD_EmissionModule/BBMOD_EmissionModule.yy",},}, {"id":{"name":"BBMOD_ShDefaultColorBatched","path":"shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.yy",},}, {"id":{"name":"BBMOD_ShInstanceID","path":"shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.yy",},}, - {"id":{"name":"__BBMOD_ShPrefilterDiffuse","path":"shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.yy",},}, + {"id":{"name":"BBMOD_ShPrefilterDiffuse","path":"shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.yy",},}, {"id":{"name":"OItem","path":"objects/OItem/OItem.yy",},}, {"id":{"name":"SndWhoosh","path":"sounds/SndWhoosh/SndWhoosh.yy",},}, + {"id":{"name":"BBMOD_ShGBufferColor","path":"shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.yy",},}, {"id":{"name":"BBMOD_AddVec2OverTimeModule","path":"scripts/BBMOD_AddVec2OverTimeModule/BBMOD_AddVec2OverTimeModule.yy",},}, {"id":{"name":"BBMOD_MixRealModule","path":"scripts/BBMOD_MixRealModule/BBMOD_MixRealModule.yy",},}, {"id":{"name":"SprSplatmap","path":"sprites/SprSplatmap/SprSplatmap.yy",},}, {"id":{"name":"__bbmod_d3d11","path":"scripts/__bbmod_d3d11/__bbmod_d3d11.yy",},}, {"id":{"name":"BBMOD_MixVec2FromHealthModule","path":"scripts/BBMOD_MixVec2FromHealthModule/BBMOD_MixVec2FromHealthModule.yy",},}, - {"id":{"name":"__BBMOD_ShCheckMRT","path":"shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.yy",},}, + {"id":{"name":"BBMOD_ShCheckMRT","path":"shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.yy",},}, {"id":{"name":"BBMOD_AddVec3OverTimeModule","path":"scripts/BBMOD_AddVec3OverTimeModule/BBMOD_AddVec3OverTimeModule.yy",},}, {"id":{"name":"BBMOD_EParticle","path":"scripts/BBMOD_EParticle/BBMOD_EParticle.yy",},}, {"id":{"name":"bbmod_surface_check","path":"scripts/bbmod_surface_check/bbmod_surface_check.yy",},}, @@ -275,9 +293,11 @@ {"id":{"name":"SndFootstep9","path":"sounds/SndFootstep9/SndFootstep9.yy",},}, {"id":{"name":"SndFootstep5","path":"sounds/SndFootstep5/SndFootstep5.yy",},}, {"id":{"name":"BBMOD_Resource","path":"scripts/BBMOD_Resource/BBMOD_Resource.yy",},}, + {"id":{"name":"BBMOD_ShGBufferColorBatched","path":"shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.yy",},}, {"id":{"name":"OZombie","path":"objects/OZombie/OZombie.yy",},}, {"id":{"name":"SndShell3","path":"sounds/SndShell3/SndShell3.yy",},}, {"id":{"name":"BBMOD_SprDefaultSpecularColor","path":"sprites/BBMOD_SprDefaultSpecularColor/BBMOD_SprDefaultSpecularColor.yy",},}, + {"id":{"name":"BBMOD_ShGBufferExtractRGB","path":"shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.yy",},}, {"id":{"name":"BBMOD_AddVec3OnCollisionModule","path":"scripts/BBMOD_AddVec3OnCollisionModule/BBMOD_AddVec3OnCollisionModule.yy",},}, {"id":{"name":"BBMOD_EAntialiasing","path":"scripts/BBMOD_EAntialiasing/BBMOD_EAntialiasing.yy",},}, {"id":{"name":"BBMOD_MixVec4FromHealthModule","path":"scripts/BBMOD_MixVec4FromHealthModule/BBMOD_MixVec4FromHealthModule.yy",},}, @@ -288,9 +308,10 @@ {"id":{"name":"BBMOD_ShPostProcess","path":"shaders/BBMOD_ShPostProcess/BBMOD_ShPostProcess.yy",},}, {"id":{"name":"BBMOD_ShDefaultColorAnimated","path":"shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.yy",},}, {"id":{"name":"ShZombieDepth","path":"shaders/ShZombieDepth/ShZombieDepth.yy",},}, + {"id":{"name":"__bbmod_matrix_proj_get_tanaspect","path":"scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.yy",},}, {"id":{"name":"BBMOD_TerrainLayer","path":"scripts/BBMOD_TerrainLayer/BBMOD_TerrainLayer.yy",},}, {"id":{"name":"BBMOD_DualQuaternion","path":"scripts/BBMOD_DualQuaternion/BBMOD_DualQuaternion.yy",},}, - {"id":{"name":"__BBMOD_ShPrefilterSpecular","path":"shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.yy",},}, + {"id":{"name":"BBMOD_ShPrefilterSpecular","path":"shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.yy",},}, {"id":{"name":"BBMOD_SpotLight","path":"scripts/BBMOD_SpotLight/BBMOD_SpotLight.yy",},}, {"id":{"name":"BBMOD_DefaultLightmapMaterial","path":"scripts/BBMOD_DefaultLightmapMaterial/BBMOD_DefaultLightmapMaterial.yy",},}, {"id":{"name":"BBMOD_MixColorOverTimeModule","path":"scripts/BBMOD_MixColorOverTimeModule/BBMOD_MixColorOverTimeModule.yy",},}, @@ -326,8 +347,10 @@ {"id":{"name":"SprHeightmap","path":"sprites/SprHeightmap/SprHeightmap.yy",},}, {"id":{"name":"BBMOD_ShGizmoSelect","path":"shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy",},}, {"id":{"name":"BBMOD_MixVec3FromHealthModule","path":"scripts/BBMOD_MixVec3FromHealthModule/BBMOD_MixVec3FromHealthModule.yy",},}, + {"id":{"name":"BBMOD_ShGBufferColorAnimated","path":"shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.yy",},}, {"id":{"name":"BBMOD_AABBEmissionModule","path":"scripts/BBMOD_AABBEmissionModule/BBMOD_AABBEmissionModule.yy",},}, {"id":{"name":"BBMOD_ShDefaultDepth","path":"shaders/BBMOD_ShDefaultDepth/BBMOD_ShDefaultDepth.yy",},}, + {"id":{"name":"BBMOD_ShDeferredFullscreen","path":"shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.yy",},}, {"id":{"name":"BBMOD_ShDefaultLightmap","path":"shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.yy",},}, {"id":{"name":"bbmod_mrt_is_supported","path":"scripts/bbmod_mrt_is_supported/bbmod_mrt_is_supported.yy",},}, {"id":{"name":"BBMOD_Collider","path":"scripts/BBMOD_Collider/BBMOD_Collider.yy",},}, @@ -347,8 +370,10 @@ {"id":{"name":"BBMOD_DragModule","path":"scripts/BBMOD_DragModule/BBMOD_DragModule.yy",},}, {"id":{"name":"BBMOD_MixVec4OverTimeModule","path":"scripts/BBMOD_MixVec4OverTimeModule/BBMOD_MixVec4OverTimeModule.yy",},}, {"id":{"name":"BBMOD_AnimationPlayer","path":"scripts/BBMOD_AnimationPlayer/BBMOD_AnimationPlayer.yy",},}, + {"id":{"name":"BBMOD_ShFogAndDepthMask","path":"shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.yy",},}, {"id":{"name":"__bbmod_logging","path":"scripts/__bbmod_logging/__bbmod_logging.yy",},}, {"id":{"name":"OFloatingText","path":"objects/OFloatingText/OFloatingText.yy",},}, + {"id":{"name":"BBMOD_ShGBufferAnimated","path":"shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.yy",},}, {"id":{"name":"BBMOD_AABBCollider","path":"scripts/BBMOD_AABBCollider/BBMOD_AABBCollider.yy",},}, {"id":{"name":"BBMOD_AnimationStateMachine","path":"scripts/BBMOD_AnimationStateMachine/BBMOD_AnimationStateMachine.yy",},}, {"id":{"name":"BBMOD_AnimationInstance","path":"scripts/BBMOD_AnimationInstance/BBMOD_AnimationInstance.yy",},}, @@ -383,6 +408,7 @@ {"id":{"name":"BBMOD_ShParticleDepth","path":"shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.yy",},}, {"id":{"name":"BBMOD_AttractorModule","path":"scripts/BBMOD_AttractorModule/BBMOD_AttractorModule.yy",},}, {"id":{"name":"BBMOD_MixColorModule","path":"scripts/BBMOD_MixColorModule/BBMOD_MixColorModule.yy",},}, + {"id":{"name":"__bbmod_shader_set","path":"scripts/__bbmod_shader_set/__bbmod_shader_set.yy",},}, {"id":{"name":"MatZombie","path":"scripts/MatZombie/MatZombie.yy",},}, {"id":{"name":"__bbmod_blendmode","path":"scripts/__bbmod_blendmode/__bbmod_blendmode.yy",},}, {"id":{"name":"BBMOD_ParticleEmitter","path":"scripts/BBMOD_ParticleEmitter/BBMOD_ParticleEmitter.yy",},}, @@ -415,15 +441,17 @@ {"id":{"name":"BBMOD_ShFXAA","path":"shaders/BBMOD_ShFXAA/BBMOD_ShFXAA.yy",},}, {"id":{"name":"BBMOD_DynamicBatch","path":"scripts/BBMOD_DynamicBatch/BBMOD_DynamicBatch.yy",},}, {"id":{"name":"BBMOD_MixQuaternionOverTimeModule","path":"scripts/BBMOD_MixQuaternionOverTimeModule/BBMOD_MixQuaternionOverTimeModule.yy",},}, - {"id":{"name":"__BBMOD_ShMixRGBM","path":"shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.yy",},}, + {"id":{"name":"BBMOD_ShMixRGBM","path":"shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.yy",},}, {"id":{"name":"OGunfireEmitter","path":"objects/OGunfireEmitter/OGunfireEmitter.yy",},}, {"id":{"name":"BBMOD_ShInstanceIDBatched","path":"shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy",},}, + {"id":{"name":"BBMOD_ShGBufferBatched","path":"shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.yy",},}, {"id":{"name":"OSky","path":"objects/OSky/OSky.yy",},}, {"id":{"name":"BBMOD_MixVec2Module","path":"scripts/BBMOD_MixVec2Module/BBMOD_MixVec2Module.yy",},}, {"id":{"name":"BBMOD_BaseRenderer","path":"scripts/BBMOD_BaseRenderer/BBMOD_BaseRenderer.yy",},}, {"id":{"name":"OGun","path":"objects/OGun/OGun.yy",},}, {"id":{"name":"SndShell1","path":"sounds/SndShell1/SndShell1.yy",},}, {"id":{"name":"BBMOD_SprCheckerboard","path":"sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy",},}, + {"id":{"name":"ShZombieGBuffer","path":"shaders/ShZombieGBuffer/ShZombieGBuffer.yy",},}, {"id":{"name":"GunfireParticleSystem","path":"scripts/GunfireParticleSystem/GunfireParticleSystem.yy",},}, {"id":{"name":"BBMOD_Shader","path":"scripts/BBMOD_Shader/BBMOD_Shader.yy",},}, {"id":{"name":"BBMOD_ShDefaultDepthColorBatched","path":"shaders/BBMOD_ShDefaultDepthColorBatched/BBMOD_ShDefaultDepthColorBatched.yy",},}, @@ -435,6 +463,7 @@ {"id":{"name":"BBMOD_SetColorModule","path":"scripts/BBMOD_SetColorModule/BBMOD_SetColorModule.yy",},}, {"id":{"name":"SndGunshot4","path":"sounds/SndGunshot4/SndGunshot4.yy",},}, {"id":{"name":"BBMOD_ShDefaultDepthBatched","path":"shaders/BBMOD_ShDefaultDepthBatched/BBMOD_ShDefaultDepthBatched.yy",},}, + {"id":{"name":"BBMOD_ShHDRToSDR","path":"shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.yy",},}, {"id":{"name":"Fnt16","path":"fonts/Fnt16/Fnt16.yy",},}, {"id":{"name":"BBMOD_ReflectionProbe","path":"scripts/BBMOD_ReflectionProbe/BBMOD_ReflectionProbe.yy",},}, {"id":{"name":"BBMOD_RaycastResult","path":"scripts/BBMOD_RaycastResult/BBMOD_RaycastResult.yy",},}, diff --git a/BBMOD_GML/ExpandShaders.py b/BBMOD_GML/ExpandShaders.py index 5e1f1cce..adf0bb3f 100755 --- a/BBMOD_GML/ExpandShaders.py +++ b/BBMOD_GML/ExpandShaders.py @@ -42,6 +42,7 @@ def combine(*_args: list[dict]) -> dict: PBR = { "X_PBR": 1 } TERRAIN = { "X_TERRAIN": 1 } OUTPUT_DEPTH = { "X_OUTPUT_DEPTH": 1 } +OUTPUT_GBUFFER = combine({ "X_OUTPUT_GBUFFER": 1 }, PBR) ID = { "X_ID": 1 } # Default shaders @@ -93,8 +94,18 @@ def combine(*_args: list[dict]) -> dict: expand_shader("BBMOD_ShTerrainUnlit", combine(TERRAIN)) expand_shader("BBMOD_ShTerrain", combine(TERRAIN, PBR)) +# G-buffer +expand_shader("BBMOD_ShGBuffer", combine(OUTPUT_GBUFFER)) +expand_shader("BBMOD_ShGBufferAnimated", combine(OUTPUT_GBUFFER, ANIMATED)) +expand_shader("BBMOD_ShGBufferBatched", combine(OUTPUT_GBUFFER, BATCHED)) +expand_shader("BBMOD_ShGBufferColor", combine(OUTPUT_GBUFFER, COLOR)) +expand_shader("BBMOD_ShGBufferColorAnimated", combine(OUTPUT_GBUFFER, COLOR, ANIMATED)) +expand_shader("BBMOD_ShGBufferColorBatched", combine(OUTPUT_GBUFFER, COLOR, BATCHED)) +expand_shader("BBMOD_ShGBufferTerrain", combine(TERRAIN, OUTPUT_GBUFFER)) + # Zombie shaders ZOMBIE = combine({ "X_ZOMBIE": 1 }, ANIMATED) expand_shader("ShZombie", combine(ZOMBIE, PBR)) expand_shader("ShZombieDepth", combine(ZOMBIE, OUTPUT_DEPTH)) +expand_shader("ShZombieGBuffer", combine(ZOMBIE, OUTPUT_GBUFFER)) diff --git a/BBMOD_GML/Xpanda b/BBMOD_GML/Xpanda index 97426dea..fcec2552 160000 --- a/BBMOD_GML/Xpanda +++ b/BBMOD_GML/Xpanda @@ -1 +1 @@ -Subproject commit 97426dea9f19e4061c356f846e170d29989983e4 +Subproject commit fcec2552230aaeb849f41227269fad7293ba433d diff --git a/BBMOD_GML/Xshaders/DoDirectionalLightPS.xsh b/BBMOD_GML/Xshaders/DoDirectionalLightPS.xsh index 0849e3e2..ecedf224 100644 --- a/BBMOD_GML/Xshaders/DoDirectionalLightPS.xsh +++ b/BBMOD_GML/Xshaders/DoDirectionalLightPS.xsh @@ -1,11 +1,11 @@ #pragma include("Material.xsh") -#if defined(X_PBR) -#if !defined(X_TERRAIN) -#pragma include("CheapSubsurface.xsh") +#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) && !defined(X_PARTICLES) +# pragma include("CheapSubsurface.xsh") #endif -#pragma include("SpecularGGX.xsh") +#if defined(X_PBR) && !defined(X_PARTICLES) +# pragma include("SpecularGGX.xsh") #else -#pragma include("SpecularBlinnPhong.xsh") +# pragma include("SpecularBlinnPhong.xsh") #endif void DoDirectionalLightPS( @@ -22,12 +22,12 @@ void DoDirectionalLightPS( { vec3 L = normalize(-direction); float NdotL = max(dot(N, L), 0.0); -#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) +#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) && !defined(X_PARTICLES) subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); #endif color *= (1.0 - shadow) * NdotL; diffuse += color; -#if defined(X_PBR) +#if defined(X_PBR) && !defined(X_PARTICLES) specular += color * SpecularGGX(m, N, V, L); #else specular += color * SpecularBlinnPhong(m, N, V, L); diff --git a/BBMOD_GML/Xshaders/DoPointLightPS.xsh b/BBMOD_GML/Xshaders/DoPointLightPS.xsh index 602530cc..f5073900 100644 --- a/BBMOD_GML/Xshaders/DoPointLightPS.xsh +++ b/BBMOD_GML/Xshaders/DoPointLightPS.xsh @@ -1,11 +1,11 @@ #pragma include("Material.xsh") -#if defined(X_PBR) -#if !defined(X_TERRAIN) -#pragma include("CheapSubsurface.xsh") +#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) && !defined(X_PARTICLES) +# pragma include("CheapSubsurface.xsh") #endif -#pragma include("SpecularGGX.xsh") +#if defined(X_PBR) && !defined(X_PARTICLES) +# pragma include("SpecularGGX.xsh") #else -#pragma include("SpecularBlinnPhong.xsh") +# pragma include("SpecularBlinnPhong.xsh") #endif void DoPointLightPS( @@ -27,12 +27,12 @@ void DoPointLightPS( float att = clamp(1.0 - (dist / range), 0.0, 1.0); att *= att; float NdotL = max(dot(N, L), 0.0); -#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) +#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) && !defined(X_PARTICLES) subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); #endif color *= (1.0 - shadow) * NdotL * att; diffuse += color; -#if defined(X_PBR) +#if defined(X_PBR) && !defined(X_PARTICLES) specular += color * SpecularGGX(m, N, V, L); #else specular += color * SpecularBlinnPhong(m, N, V, L); diff --git a/BBMOD_GML/Xshaders/DoSpotLightPS.xsh b/BBMOD_GML/Xshaders/DoSpotLightPS.xsh index 1a27a551..3f15cf85 100644 --- a/BBMOD_GML/Xshaders/DoSpotLightPS.xsh +++ b/BBMOD_GML/Xshaders/DoSpotLightPS.xsh @@ -1,11 +1,11 @@ #pragma include("Material.xsh") -#if defined(X_PBR) -#if !defined(X_TERRAIN) -#pragma include("CheapSubsurface.xsh") +#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) && !defined(X_PARTICLES) +# pragma include("CheapSubsurface.xsh") #endif -#pragma include("SpecularGGX.xsh") +#if defined(X_PBR) && !defined(X_PARTICLES) +# pragma include("SpecularGGX.xsh") #else -#pragma include("SpecularBlinnPhong.xsh") +# pragma include("SpecularBlinnPhong.xsh") #endif void DoSpotLightPS( @@ -31,12 +31,12 @@ void DoSpotLightPS( float theta = dot(L, normalize(-direction)); float epsilon = dcosInner - dcosOuter; float intensity = clamp((theta - dcosOuter) / epsilon, 0.0, 1.0); -#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) +#if defined(X_PBR) && !defined(X_TERRAIN) && !defined(X_LIGHTMAP) && !defined(X_PARTICLES) subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); #endif color *= (1.0 - shadow) * intensity * att; diffuse += color; -#if defined(X_PBR) +#if defined(X_PBR) && !defined(X_PARTICLES) specular += color * SpecularGGX(m, N, V, L); #else specular += color * SpecularBlinnPhong(m, N, V, L); diff --git a/BBMOD_GML/Xshaders/MetallicMaterial.xsh b/BBMOD_GML/Xshaders/MetallicMaterial.xsh index 62b4fc63..276ef541 100644 --- a/BBMOD_GML/Xshaders/MetallicMaterial.xsh +++ b/BBMOD_GML/Xshaders/MetallicMaterial.xsh @@ -22,7 +22,7 @@ Material UnpackMaterial( #if !defined(X_TERRAIN) float isMetallic, sampler2D texMaterial, -#if !defined(X_LIGHTMAP) +#if !defined(X_LIGHTMAP) && !defined(X_PARTICLES) sampler2D texSubsurface, #endif sampler2D texEmissive, @@ -95,7 +95,7 @@ Material UnpackMaterial( m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); } -#if !defined(X_LIGHTMAP) +#if !defined(X_LIGHTMAP) && !defined(X_PARTICLES) // Subsurface (color and intensity) vec4 subsurface = texture2D(texSubsurface, uv); m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); diff --git a/BBMOD_GML/Xshaders/PBRShader.xsh b/BBMOD_GML/Xshaders/PBRShader.xsh index dea4b325..931ada32 100644 --- a/BBMOD_GML/Xshaders/PBRShader.xsh +++ b/BBMOD_GML/Xshaders/PBRShader.xsh @@ -34,19 +34,32 @@ void PBRShader(Material material, float depth) #if !defined(X_2D) if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } #endif @@ -130,7 +143,10 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } diff --git a/BBMOD_GML/Xshaders/Uber_PS.xsh b/BBMOD_GML/Xshaders/Uber_PS.xsh index 2a55369b..c79d45ee 100644 --- a/BBMOD_GML/Xshaders/Uber_PS.xsh +++ b/BBMOD_GML/Xshaders/Uber_PS.xsh @@ -128,7 +128,7 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; -#if !defined(X_OUTPUT_DEPTH) +#if !defined(X_OUTPUT_DEPTH) && !defined(X_OUTPUT_GBUFFER) #if defined(X_PARTICLES) //////////////////////////////////////////////////////////////////////////////// // Soft particles @@ -197,71 +197,110 @@ uniform vec4 bbmod_LightPunctualDataA[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]; uniform vec3 bbmod_LightPunctualDataB[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]; #endif // X_PBR +#if defined(X_PBR) && !defined(X_OUTPUT_GBUFFER) +//////////////////////////////////////////////////////////////////////////////// +// Shadow mapping + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnablePS; +// Shadowmap texture +uniform sampler2D bbmod_Shadowmap; +// (1.0/shadowmapWidth, 1.0/shadowmapHeight) +uniform vec2 bbmod_ShadowmapTexel; +// The area that the shadowmap captures +uniform float bbmod_ShadowmapArea; +// The range over which meshes smoothly transition into shadow. +uniform float bbmod_ShadowmapBias; +// The index of the light that casts shadows. Use -1 for the directional light. +uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; +#endif // defined(X_PBR) && !defined(X_OUTPUT_GBUFFER) +#endif // !defined(X_OUTPUT_DEPTH) && !defined(X_OUTPUT_GBUFFER) + #if defined(X_TERRAIN) //////////////////////////////////////////////////////////////////////////////// // Terrain +// First layer: // RGB: Base color, A: Opacity #define bbmod_TerrainBaseOpacity0 gm_BaseTexture // If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness0; // RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW0; -// Splatmap texture -uniform sampler2D bbmod_Splatmap; // Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex0; + +// Splatmap texture +uniform sampler2D bbmod_Splatmap; // Colormap texture uniform sampler2D bbmod_Colormap; -#if !defined(X_PBR) && !(defined(X_OUTPUT_DEPTH) || defined(X_ID)) +#if (!defined(X_PBR) || defined(X_OUTPUT_GBUFFER)) && !(defined(X_OUTPUT_DEPTH) || defined(X_ID)) +// Second layer: +// RGB: Base color, A: Opacity uniform sampler2D bbmod_TerrainBaseOpacity1; +// If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness1; +// RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW1; +// Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex1; +// Third layer: +// RGB: Base color, A: Opacity uniform sampler2D bbmod_TerrainBaseOpacity2; +// If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness2; +// RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW2; +// Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex2; #endif #endif // X_TERRAIN -#if defined(X_PBR) +#if defined(X_OUTPUT_DEPTH) //////////////////////////////////////////////////////////////////////////////// -// Shadow mapping +// Writing shadow maps -// 1.0 to enable shadows -uniform float bbmod_ShadowmapEnablePS; -// Shadowmap texture -uniform sampler2D bbmod_Shadowmap; -// (1.0/shadowmapWidth, 1.0/shadowmapHeight) -uniform vec2 bbmod_ShadowmapTexel; -// The area that the shadowmap captures -uniform float bbmod_ShadowmapArea; -// The range over which meshes smoothly transition into shadow. -uniform float bbmod_ShadowmapBias; -// The index of the light that casts shadows. Use -1 for the directional light. -uniform float bbmod_ShadowCasterIndex; -#endif // X_PBR -#endif // !X_OUTPUT_DEPTH +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; +#endif + +#if defined(X_OUTPUT_GBUFFER) && !defined(X_TERRAIN) +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; +#endif + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // // Includes // -#if !defined(X_ID) -#if defined(X_OUTPUT_DEPTH) -#pragma include("DepthShader.xsh") -#else // X_OUTPUT_DEPTH -#if defined(X_PBR) -#pragma include("PBRShader.xsh") -#else // X_PBR -#pragma include("UnlitShader.xsh") -#endif // !X_PBR -#endif // !X_OUTPUT_DEPTH -#endif // !X_ID +#if defined(X_ID) +#elif defined(X_OUTPUT_DEPTH) +# pragma include("DepthShader.xsh") +#elif defined(X_OUTPUT_GBUFFER) +# pragma include("DepthEncoding.xsh") +# pragma include("BestFitNormals.xsh") +# if defined(X_PBR) +# pragma include("MetallicMaterial.xsh") +# endif +#elif defined(X_PBR) +# pragma include("PBRShader.xsh") +#else +# pragma include("UnlitShader.xsh") +#endif //////////////////////////////////////////////////////////////////////////////// // @@ -293,12 +332,12 @@ void main() gl_FragColor = bbmod_InstanceID; #endif #elif defined(X_OUTPUT_DEPTH) - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); #endif #else #if defined(X_TERRAIN) -#if defined(X_PBR) +#if defined(X_PBR) && !defined(X_OUTPUT_GBUFFER) Material material = UnpackMaterial( bbmod_TerrainBaseOpacity0, bbmod_TerrainIsRoughness0, @@ -367,8 +406,33 @@ void main() material.Base *= layerStrengthInv; material.Opacity *= layerStrengthInv; + material.Base += layerStrength * material1.Base; material.Opacity += layerStrength * material1.Opacity; + + #if defined(X_PBR) + material.Normal *= layerStrengthInv; + material.Metallic *= layerStrengthInv; + material.Roughness *= layerStrengthInv; + material.Specular *= layerStrengthInv; + material.Smoothness *= layerStrengthInv; + material.SpecularPower *= layerStrengthInv; + material.AO *= layerStrengthInv; + material.Emissive *= layerStrengthInv; + material.Subsurface *= layerStrengthInv; + material.Lightmap *= layerStrengthInv; + + material.Normal += layerStrength * material1.Normal; + material.Metallic += layerStrength * material1.Metallic; + material.Roughness += layerStrength * material1.Roughness; + material.Specular += layerStrength * material1.Specular; + material.Smoothness += layerStrength * material1.Smoothness; + material.SpecularPower += layerStrength * material1.SpecularPower; + material.AO += layerStrength * material1.AO; + material.Emissive += layerStrength * material1.Emissive; + material.Subsurface += layerStrength * material1.Subsurface; + material.Lightmap += layerStrength * material1.Lightmap; + #endif } if (bbmod_SplatmapIndex2 >= 0) @@ -382,8 +446,33 @@ void main() material.Base *= layerStrengthInv; material.Opacity *= layerStrengthInv; + material.Base += layerStrength * material2.Base; material.Opacity += layerStrength * material2.Opacity; + + #if defined(X_PBR) + material.Normal *= layerStrengthInv; + material.Metallic *= layerStrengthInv; + material.Roughness *= layerStrengthInv; + material.Specular *= layerStrengthInv; + material.Smoothness *= layerStrengthInv; + material.SpecularPower *= layerStrengthInv; + material.AO *= layerStrengthInv; + material.Emissive *= layerStrengthInv; + material.Subsurface *= layerStrengthInv; + material.Lightmap *= layerStrengthInv; + + material.Normal += layerStrength * material2.Normal; + material.Metallic += layerStrength * material2.Metallic; + material.Roughness += layerStrength * material2.Roughness; + material.Specular += layerStrength * material2.Specular; + material.Smoothness += layerStrength * material2.Smoothness; + material.SpecularPower += layerStrength * material2.SpecularPower; + material.AO += layerStrength * material2.AO; + material.Emissive += layerStrength * material2.Emissive; + material.Subsurface += layerStrength * material2.Subsurface; + material.Lightmap += layerStrength * material2.Lightmap; + #endif } // Colormap @@ -396,7 +485,7 @@ void main() bbmod_NormalW, bbmod_IsMetallic, bbmod_Material, -#if !defined(X_LIGHTMAP) +#if !defined(X_LIGHTMAP) && !defined(X_PARTICLES) bbmod_Subsurface, #endif bbmod_Emissive, @@ -425,6 +514,13 @@ void main() { discard; } + material.Emissive = mix( + material.Emissive, + xGammaToLinear(u_vDissolveColor), + (1.0 - clamp((noise - u_fDissolveThreshold) / u_fDissolveRange, 0.0, 1.0)) * u_fDissolveThreshold); + + // Silhouette + material.Emissive = mix(material.Emissive, xGammaToLinear(u_vSilhouette.rgb), u_vSilhouette.a); #endif // X_ZOMBIE if (material.Opacity < bbmod_AlphaTest) @@ -432,21 +528,23 @@ void main() discard; } -#if defined(X_PBR) +#if defined(X_OUTPUT_GBUFFER) + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); +#if defined(X_TERRAIN) + gl_FragData[1] = vec4(material.Normal * 0.5 + 0.5, material.Roughness); +#else + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); +#endif + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +#elif defined(X_PBR) PBRShader(material, v_vPosition.z); -#else // X_PBR +#else UnlitShader(material, v_vPosition.z); -#endif // !X_PBR - -#if defined(X_ZOMBIE) - // Dissolve - gl_FragColor.rgb = mix( - gl_FragColor.rgb, - u_vDissolveColor, - (1.0 - clamp((noise - u_fDissolveThreshold) / u_fDissolveRange, 0.0, 1.0)) * u_fDissolveThreshold); - // Silhouette - gl_FragColor.rgb = mix(gl_FragColor.rgb, u_vSilhouette.rgb, u_vSilhouette.a); #endif - #endif } diff --git a/BBMOD_GML/Xshaders/Uber_VS.xsh b/BBMOD_GML/Xshaders/Uber_VS.xsh index da1552f3..d1a865bd 100644 --- a/BBMOD_GML/Xshaders/Uber_VS.xsh +++ b/BBMOD_GML/Xshaders/Uber_VS.xsh @@ -68,7 +68,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; #endif //////////////////////////////////////////////////////////////////////////////// @@ -185,7 +185,7 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } #endif } diff --git a/BBMOD_GML/Xshaders/UnlitShader.xsh b/BBMOD_GML/Xshaders/UnlitShader.xsh index c837a922..9725e46f 100644 --- a/BBMOD_GML/Xshaders/UnlitShader.xsh +++ b/BBMOD_GML/Xshaders/UnlitShader.xsh @@ -23,7 +23,11 @@ void UnlitShader(Material material, float depth) } #endif Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } diff --git a/BBMOD_GML/extensions/BBMOD_CameraHTML5/BBMOD_CameraHTML5.yy b/BBMOD_GML/extensions/BBMOD_CameraHTML5/BBMOD_CameraHTML5.yy index f8cbc44b..f3af7ded 100644 --- a/BBMOD_GML/extensions/BBMOD_CameraHTML5/BBMOD_CameraHTML5.yy +++ b/BBMOD_GML/extensions/BBMOD_CameraHTML5/BBMOD_CameraHTML5.yy @@ -16,7 +16,7 @@ "date": "2022-01-09T15:30:47.4419817+01:00", "description": "", "exportToGame": true, - "extensionVersion": "3.19.3", + "extensionVersion": "3.20.0", "files": [ {"resourceType":"GMExtensionFile","resourceVersion":"1.0","name":"","constants":[],"copyToTargets":32,"filename":"BBMOD_CameraHTML5.js","final":"","functions":[ {"resourceType":"GMExtensionFunction","resourceVersion":"1.0","name":"bbmod_html5_pointer_lock","argCount":0,"args":[],"documentation":"","externalName":"bbmod_html5_pointer_lock","help":"bbmod_html5_pointer_lock()","hidden":false,"kind":5,"returnType":2,}, diff --git a/BBMOD_GML/objects/OInit/Create_0.gml b/BBMOD_GML/objects/OInit/Create_0.gml index 7a48b592..76ab3438 100644 --- a/BBMOD_GML/objects/OInit/Create_0.gml +++ b/BBMOD_GML/objects/OInit/Create_0.gml @@ -17,9 +17,12 @@ var _sand = new BBMOD_TerrainLayer() _sand.BaseOpacity = sprite_get_texture(SprSand, 0); _sand.NormalSmoothness = sprite_get_texture(SprSand, 1); +var _deferred = bbmod_deferred_renderer_is_supported(); + global.terrain = new BBMOD_Terrain(SprHeightmap); -global.terrain.Material = BBMOD_MATERIAL_TERRAIN.clone(); +global.terrain.Material = (_deferred ? BBMOD_MATERIAL_TERRAIN_DEFERRED : BBMOD_MATERIAL_TERRAIN).clone(); global.terrain.Material.set_shader(BBMOD_ERenderPass.DepthOnly, BBMOD_SHADER_DEFAULT_DEPTH); +global.terrain.Material.set_shader(BBMOD_ERenderPass.Shadows, BBMOD_SHADER_DEFAULT_DEPTH); global.terrain.Scale = new BBMOD_Vec3(4.0, 4.0, 1.0); global.terrain.TextureRepeat = new BBMOD_Vec2(32.0); global.terrain.Layer[@ 0] = _sand; diff --git a/BBMOD_GML/objects/OMain/Create_0.gml b/BBMOD_GML/objects/OMain/Create_0.gml index c2d97b89..494d41b9 100644 --- a/BBMOD_GML/objects/OMain/Create_0.gml +++ b/BBMOD_GML/objects/OMain/Create_0.gml @@ -1,5 +1,7 @@ #macro DELTA_TIME (delta_time * global.gameSpeed) +var _deferred = bbmod_deferred_renderer_is_supported(); + // Used to pause the game (with 0.0). global.gameSpeed = 1.0; @@ -33,7 +35,7 @@ _objImporter.FlipUVVertically = true; modGun = _objImporter.import("Data/Assets/Pistol.obj"); modGun.freeze(); -var _matGunBase = BBMOD_MATERIAL_DEFAULT.clone() +var _matGunBase = (_deferred ? BBMOD_MATERIAL_DEFERRED : BBMOD_MATERIAL_DEFAULT).clone() .set_shader( BBMOD_ERenderPass.Id, BBMOD_SHADER_INSTANCE_ID) // Enable instance selecting .set_shader( @@ -57,7 +59,7 @@ modGun.Materials[@ 2] = matGun2; // Dynamically batch shells modShell = _objImporter.import("Data/Assets/Shell.obj"); -matShell = BBMOD_MATERIAL_DEFAULT_BATCHED.clone() +matShell = (_deferred ? BBMOD_MATERIAL_DEFERRED : BBMOD_MATERIAL_DEFAULT).clone() .set_shader(BBMOD_ERenderPass.Id, BBMOD_SHADER_INSTANCE_ID_BATCHED) .set_base_opacity(new BBMOD_Color().FromHex($E8DA56)) .set_specular_color(new BBMOD_Color().FromConstant($E8DA56)) @@ -74,7 +76,7 @@ _objImporter = _objImporter.destroy(); gizmo = new BBMOD_Gizmo(); gizmo.ButtonDrag = mb_right; -renderer = new BBMOD_DefaultRenderer(); +renderer = new (_deferred ? BBMOD_DeferredRenderer : BBMOD_DefaultRenderer)(); renderer.Gizmo = gizmo; renderer.ButtonSelect = mb_right; renderer.UseAppSurface = true; diff --git a/BBMOD_GML/objects/OPlayer/Create_0.gml b/BBMOD_GML/objects/OPlayer/Create_0.gml index 59284b9c..1850a507 100644 --- a/BBMOD_GML/objects/OPlayer/Create_0.gml +++ b/BBMOD_GML/objects/OPlayer/Create_0.gml @@ -20,7 +20,7 @@ punchRight = true; chainPunch = false; flashlight = new BBMOD_SpotLight(); -flashlight.RenderPass = (1 << BBMOD_ERenderPass.Forward); +flashlight.RenderPass = ~(1 << BBMOD_ERenderPass.ReflectionCapture); flashlight.CastShadows = true; flashlight.Range = 300; flashlight.Color.Alpha = 0.5; @@ -53,7 +53,8 @@ camera.MouseSensitivity = 0.75; //////////////////////////////////////////////////////////////////////////////// // Load resources matPlayer = global.resourceManager.get_or_add("matPlayer", function () { - var _material = BBMOD_MATERIAL_DEFAULT.clone() + var _deferred = bbmod_deferred_renderer_is_supported(); + var _material = (_deferred ? BBMOD_MATERIAL_DEFERRED : BBMOD_MATERIAL_DEFAULT).clone() .set_shader(BBMOD_ERenderPass.Id, BBMOD_SHADER_INSTANCE_ID) // Enable instance selecting .set_shader(BBMOD_ERenderPass.Shadows, BBMOD_SHADER_DEFAULT_DEPTH); // Enable casting shadows _material.BaseOpacity = sprite_get_texture(SprPlayer, choose(0, 1)); diff --git a/BBMOD_GML/objects/OPlayer/Step_0.gml b/BBMOD_GML/objects/OPlayer/Step_0.gml index 5bc7cbd5..b11225bb 100644 --- a/BBMOD_GML/objects/OPlayer/Step_0.gml +++ b/BBMOD_GML/objects/OPlayer/Step_0.gml @@ -257,3 +257,21 @@ if (hp <= 0.0) { room_goto(RmGameOver); } + +//////////////////////////////////////////////////////////////////////////////// +// Test: Create shadow casting point lights + +//if (keyboard_check_pressed(vk_enter)) +//{ +// var _light = new BBMOD_PointLight(); +// _light.Color = new BBMOD_Color().FromHSV( +// random(255), +// 255, +// 255 +// ); +// _light.Color.Alpha = 0.5; +// _light.Position = new BBMOD_Vec3(x, y, z + 30); +// _light.Range = random_range(50, 100); +// _light.CastShadows = true; +// bbmod_light_punctual_add(_light); +//} diff --git a/BBMOD_GML/objects/OSky/Create_0.gml b/BBMOD_GML/objects/OSky/Create_0.gml index 890e9df4..c7810459 100644 --- a/BBMOD_GML/objects/OSky/Create_0.gml +++ b/BBMOD_GML/objects/OSky/Create_0.gml @@ -18,7 +18,7 @@ matSky.BaseOpacity = -1; bbmod_light_ambient_set(BBMOD_C_BLACK); sunLight = new BBMOD_DirectionalLight(); -sunLight.CastShadows = global.day; +sunLight.CastShadows = bbmod_deferred_renderer_is_supported() || global.day; sunLight.ShadowmapResolution = 4096; bbmod_light_directional_set(sunLight); diff --git a/BBMOD_GML/objects/odissolveemitter/Create_0.gml b/BBMOD_GML/objects/odissolveemitter/Create_0.gml index 75efa02a..c0485bab 100644 --- a/BBMOD_GML/objects/odissolveemitter/Create_0.gml +++ b/BBMOD_GML/objects/odissolveemitter/Create_0.gml @@ -5,6 +5,6 @@ position = new BBMOD_Vec3(x, y, z); emitter = new BBMOD_ParticleEmitter(position, DissolveParticleSystem()); light = new BBMOD_PointLight(new BBMOD_Color(0, 255, 127, 0), position, 40); -light.RenderPass = (1 << BBMOD_ERenderPass.Forward); +light.RenderPass = ~(1 << BBMOD_ERenderPass.ReflectionCapture); bbmod_light_punctual_add(light); diff --git a/BBMOD_GML/objects/ogunfireemitter/Create_0.gml b/BBMOD_GML/objects/ogunfireemitter/Create_0.gml index 478c0b37..f83f5919 100644 --- a/BBMOD_GML/objects/ogunfireemitter/Create_0.gml +++ b/BBMOD_GML/objects/ogunfireemitter/Create_0.gml @@ -5,7 +5,7 @@ position = new BBMOD_Vec3(x, y, z); emitter = new BBMOD_ParticleEmitter(position, GunfireParticleSystem()); light = new BBMOD_PointLight(BBMOD_C_ORANGE, position, random_range(70, 80)); -light.RenderPass = (1 << BBMOD_ERenderPass.Forward); +light.RenderPass = ~(1 << BBMOD_ERenderPass.ReflectionCapture); light.Color.Alpha = random_range(2.5, 3); bbmod_light_punctual_add(light); diff --git a/BBMOD_GML/options/amazonfire/options_amazonfire.yy b/BBMOD_GML/options/amazonfire/options_amazonfire.yy index a33f5808..f8837095 100644 --- a/BBMOD_GML/options/amazonfire/options_amazonfire.yy +++ b/BBMOD_GML/options/amazonfire/options_amazonfire.yy @@ -44,5 +44,5 @@ "option_amazonfire_texture_page": "2048x2048", "option_amazonfire_tools_from_version": false, "option_amazonfire_tv_banner": "${base_options_dir}/amazonfire/tv_banner.png", - "option_amazonfire_version": "3.19.3", + "option_amazonfire_version": "3.20.0", } \ No newline at end of file diff --git a/BBMOD_GML/options/android/options_android.yy b/BBMOD_GML/options/android/options_android.yy index 4e695511..cc8c2e99 100644 --- a/BBMOD_GML/options/android/options_android.yy +++ b/BBMOD_GML/options/android/options_android.yy @@ -75,5 +75,5 @@ "option_android_tv_isgame": true, "option_android_tv_supports_leanback": true, "option_android_use_facebook": false, - "option_android_version": "3.19.3", + "option_android_version": "3.20.0", } \ No newline at end of file diff --git a/BBMOD_GML/options/html5/options_html5.yy b/BBMOD_GML/options/html5/options_html5.yy index 32d21e45..934a371d 100644 --- a/BBMOD_GML/options/html5/options_html5.yy +++ b/BBMOD_GML/options/html5/options_html5.yy @@ -28,6 +28,6 @@ "option_html5_usebuiltinfont": true, "option_html5_usebuiltinparticles": true, "option_html5_usesplash": false, - "option_html5_version": "3.19.3.0", + "option_html5_version": "3.20.0.0", "option_html5_webgl": 1, } \ No newline at end of file diff --git a/BBMOD_GML/options/ios/options_ios.yy b/BBMOD_GML/options/ios/options_ios.yy index 4e9581a6..48b9d6bf 100644 --- a/BBMOD_GML/options/ios/options_ios.yy +++ b/BBMOD_GML/options/ios/options_ios.yy @@ -42,5 +42,5 @@ "option_ios_splashscreen_background_colour": 255, "option_ios_team_id": "", "option_ios_texture_page": "2048x2048", - "option_ios_version": "3.19.3", + "option_ios_version": "3.20.0", } \ No newline at end of file diff --git a/BBMOD_GML/options/linux/options_linux.yy b/BBMOD_GML/options/linux/options_linux.yy index 43185148..946e5c7b 100644 --- a/BBMOD_GML/options/linux/options_linux.yy +++ b/BBMOD_GML/options/linux/options_linux.yy @@ -20,5 +20,5 @@ "option_linux_start_fullscreen": false, "option_linux_sync": false, "option_linux_texture_page": "2048x2048", - "option_linux_version": "3.19.3", + "option_linux_version": "3.20.0", } \ No newline at end of file diff --git a/BBMOD_GML/options/mac/options_mac.yy b/BBMOD_GML/options/mac/options_mac.yy index 4280ec9d..8858da54 100644 --- a/BBMOD_GML/options/mac/options_mac.yy +++ b/BBMOD_GML/options/mac/options_mac.yy @@ -29,7 +29,7 @@ "option_mac_start_fullscreen": false, "option_mac_team_id": "", "option_mac_texture_page": "2048x2048", - "option_mac_version": "3.19.3", + "option_mac_version": "3.20.0", "option_mac_vsync": false, "option_mac_x86_64": true, } \ No newline at end of file diff --git a/BBMOD_GML/options/operagx/options_operagx.yy b/BBMOD_GML/options/operagx/options_operagx.yy index 7cf9c655..f0bed60b 100644 --- a/BBMOD_GML/options/operagx/options_operagx.yy +++ b/BBMOD_GML/options/operagx/options_operagx.yy @@ -23,5 +23,5 @@ "option_operagx_team_id": "", "option_operagx_team_name": "", "option_operagx_texture_page": "2048x2048", - "option_operagx_version": "3.19.3.0", + "option_operagx_version": "3.20.0.0", } \ No newline at end of file diff --git a/BBMOD_GML/options/tvos/options_tvos.yy b/BBMOD_GML/options/tvos/options_tvos.yy index bffa7aea..dcdd78c4 100644 --- a/BBMOD_GML/options/tvos/options_tvos.yy +++ b/BBMOD_GML/options/tvos/options_tvos.yy @@ -24,5 +24,5 @@ "option_tvos_topshelf_2x": "${base_options_dir}/tvos/topshelf/topshelf_2x.png", "option_tvos_topshelf_wide": "${base_options_dir}/tvos/topshelf/topshelf_wide.png", "option_tvos_topshelf_wide_2x": "${base_options_dir}/tvos/topshelf/topshelf_wide_2x.png", - "option_tvos_version": "3.19.3", + "option_tvos_version": "3.20.0", } \ No newline at end of file diff --git a/BBMOD_GML/options/windows/options_windows.yy b/BBMOD_GML/options/windows/options_windows.yy index 94a0e4be..0f9d1c1e 100644 --- a/BBMOD_GML/options/windows/options_windows.yy +++ b/BBMOD_GML/options/windows/options_windows.yy @@ -29,6 +29,6 @@ "option_windows_steam_use_alternative_launcher": false, "option_windows_texture_page": "2048x2048", "option_windows_use_splash": false, - "option_windows_version": "3.19.3.0", + "option_windows_version": "3.20.0.0", "option_windows_vsync": false, } \ No newline at end of file diff --git a/BBMOD_GML/options/windowsuap/options_windowsuap.yy b/BBMOD_GML/options/windowsuap/options_windowsuap.yy index be2a9ad1..aaeebe86 100644 --- a/BBMOD_GML/options/windowsuap/options_windowsuap.yy +++ b/BBMOD_GML/options/windowsuap/options_windowsuap.yy @@ -4,7 +4,7 @@ "option_windowsuap_publisher_display_name": "YourPublisherName", "option_windowsuap_package_display_name": "YourPackageDisplayName", "option_windowsuap_description": "Your Description", - "option_windowsuap_version": "3.19.3.0", + "option_windowsuap_version": "3.20.0.0", "option_windowsuap_orient_portrait": true, "option_windowsuap_orient_portrait_flipped": true, "option_windowsuap_orient_landscape": true, diff --git a/BBMOD_GML/scripts/BBMOD_AnimationPlayer/BBMOD_AnimationPlayer.gml b/BBMOD_GML/scripts/BBMOD_AnimationPlayer/BBMOD_AnimationPlayer.gml index a636ea48..61196132 100644 --- a/BBMOD_GML/scripts/BBMOD_AnimationPlayer/BBMOD_AnimationPlayer.gml +++ b/BBMOD_GML/scripts/BBMOD_AnimationPlayer/BBMOD_AnimationPlayer.gml @@ -55,7 +55,6 @@ /// animationPlayer.update(delta_time); /// /// /// @desc Draw event of OCharacter -/// bbmod_material_reset(); /// animationPlayer.render(); /// bbmod_material_reset(); /// ``` diff --git a/BBMOD_GML/scripts/BBMOD_BaseCamera/BBMOD_BaseCamera.gml b/BBMOD_GML/scripts/BBMOD_BaseCamera/BBMOD_BaseCamera.gml index 61d4e01c..6db50f6e 100644 --- a/BBMOD_GML/scripts/BBMOD_BaseCamera/BBMOD_BaseCamera.gml +++ b/BBMOD_GML/scripts/BBMOD_BaseCamera/BBMOD_BaseCamera.gml @@ -345,7 +345,6 @@ function BBMOD_BaseCamera() constructor /// Following code renders a model from the camera's view. /// ```gml /// camera.apply(); - /// bbmod_material_reset(); /// model.submit(); /// bbmod_material_reset(); /// ``` diff --git a/BBMOD_GML/scripts/BBMOD_BaseRenderer/BBMOD_BaseRenderer.gml b/BBMOD_GML/scripts/BBMOD_BaseRenderer/BBMOD_BaseRenderer.gml index 0f60bf78..58168c23 100644 --- a/BBMOD_GML/scripts/BBMOD_BaseRenderer/BBMOD_BaseRenderer.gml +++ b/BBMOD_GML/scripts/BBMOD_BaseRenderer/BBMOD_BaseRenderer.gml @@ -8,8 +8,8 @@ global.__bbmodRendererCurrent = undefined; /// /// @implements {BBMOD_IDestructible} /// -/// @desc Base struct for renderers, which execute -/// [render commands](./BBMOD_RenderCommand.html) created with method +/// @desc Base struct for renderers. Renderers execute +/// [render commands](./BBMOD_ERenderCommand.html) created with method /// [render](./BBMOD_Model.render.html). function BBMOD_BaseRenderer() constructor { @@ -103,10 +103,21 @@ function BBMOD_BaseRenderer() constructor /// @see BBMOD_Light.ShadowmapResolution EnableShadows = false; - /// @var {Id.Surface} The surface used for rendering the scene's depth from the - /// directional light's view. + /// @var {Id.DsList} /// @private - __surShadowmap = -1; + __shadowmapLights = ds_list_create(); + + /// @var {Id.DsList} + /// @private + __shadowmapHealth = ds_list_create(); + + /// @var {Id.DsMap} + /// @private + __shadowmapSurfaces = ds_map_create(); + + /// @var {Id.DsMap} + /// @private + __shadowmapCubes = ds_map_create(); /// @var {Real} When rendering shadows, offsets vertex position by its normal /// scaled by this value. Defaults to 1. Increasing the value can remove some @@ -136,6 +147,45 @@ function BBMOD_BaseRenderer() constructor /// @private __surProbe2 = -1; + /// @var {Bool} Enables screen-space ambient occlusion. This requires + /// the depth buffer. Defaults to `false`. Enabling this requires the + /// [SSAO submodule](./SSAOSubmodule.html)! + /// @see BBMOD_DefaultRenderer.EnableGBuffer + EnableSSAO = false; + + /// @var {Id.Surface} The SSAO surface. + /// @private + __surSSAO = -1; + + /// @var {Id.Surface} Surface used for blurring SSAO. + /// @private + __surWork = -1; + + /// @var {Real} Resolution multiplier for SSAO surface. Defaults to 1. + SSAOScale = 1.0; + + /// @var {Real} Screen-space radius of SSAO. Default value is 16. + SSAORadius = 16.0; + + /// @var {Real} Strength of the SSAO effect. Should be greater than 0. + /// Default value is 1. + SSAOPower = 1.0; + + /// @var {Real} SSAO angle bias in radians. Default value is 0.03. + SSAOAngleBias = 0.03; + + /// @var {Real} Maximum depth difference of SSAO samples. Samples farther + /// away from the origin than this will not contribute to the effect. + /// Default value is 10. + SSAODepthRange = 10.0; + + /// @var {Real} Defaults to 0.01. Increase to fix self-occlusion. + SSAOSelfOcclusionBias = 0.01; + + /// @var {Real} Maximum depth difference over which can be SSAO samples + /// blurred. Defaults to 2. + SSAOBlurDepthRange = 2.0; + /// @func get_width() /// /// @desc Retrieves the width of the renderer on the screen. @@ -374,7 +424,163 @@ function BBMOD_BaseRenderer() constructor return self; }; - /// @func __render_shadowmap() + /// @func __incr_shadowmap_health(_light) + /// + /// @desc Increments health of a light's shadowmap. + /// + /// @param {Struct.BBMOD_Light} _light The light. + /// + /// @private + static __incr_shadowmap_health = function (_light) + { + var _lightIndex = ds_list_find_index(__shadowmapLights, _light); + if (_lightIndex == -1) + { + _lightIndex = ds_list_size(__shadowmapLights); + ds_list_add(__shadowmapLights, _light); + ds_list_add(__shadowmapHealth, 1); + } + ++__shadowmapHealth[| _lightIndex]; + }; + + /// @func __gc_collect_shadowmaps() + /// + /// @desc Decrements health of all shadowmaps and frees them from memory + /// when it reaches or drops below 0. + /// + /// @private + static __gc_collect_shadowmaps = function () + { + for (var i = ds_list_size(__shadowmapLights) - 1; i >= 0; --i) + { + var _light = __shadowmapLights[| i]; + if (--__shadowmapHealth[| i] <= 0) + { + ds_list_delete(__shadowmapLights, i); + ds_list_delete(__shadowmapHealth, i); + + if (ds_map_exists(__shadowmapSurfaces, _light)) + { + var _surface = __shadowmapSurfaces[? _light]; + if (surface_exists(_surface)) + { + surface_free(_surface); + } + ds_map_delete(__shadowmapSurfaces, _light); + } + + if (ds_map_exists(__shadowmapCubes, _light)) + { + __shadowmapCubes[? _light].destroy(); + ds_map_delete(__shadowmapCubes, _light); + } + } + } + }; + + /// @func __render_shadowmap_impl(_light) + /// + /// @desc Re-captures light's shadowmap if required and always increments + /// shadowmap health. + /// + /// @param {Struct.BBMOD_Light} _light The light to capture shadowmap for. + /// + /// @private + static __render_shadowmap_impl = function (_light) + { + static _renderQueues = bbmod_render_queues_get(); + + __incr_shadowmap_health(_light); + + if ((!_light.Static || _light.NeedsUpdate) + && _light.__frameskipCurrent == 0) + { + var _shadowCaster = _light; + var _shadowmapMatrix; + var _shadowmapZFar = _light.__getZFar(); + var _surShadowmap = -1; + + bbmod_render_pass_set(BBMOD_ERenderPass.Shadows); + + if (is_instanceof(_light, BBMOD_PointLight)) + { + var _cubemap; + if (ds_map_exists(__shadowmapCubes, _light)) + { + _cubemap = __shadowmapCubes[? _light]; + } + else + { + _cubemap = new BBMOD_Cubemap(_light.ShadowmapResolution); + __shadowmapCubes[? _light] = _cubemap; + } + + _light.Position.Copy(_cubemap.Position); + bbmod_shader_set_global_f(BBMOD_U_ZFAR, _shadowmapZFar); + bbmod_shader_set_global_f("u_fOutputDistance", 1.0); + + while (_cubemap.set_target()) + { + draw_clear(c_red); + var _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + _cubemap.reset_target(); + } + bbmod_material_reset(); + + bbmod_shader_set_global_f("u_fOutputDistance", 0.0); + + _cubemap.to_single_surface(); + _cubemap.to_octahedron(); + __shadowmapSurfaces[? _light] = _cubemap.SurfaceOctahedron; + } + else + { + var _surShadowmapOld = -1; + if (ds_map_exists(__shadowmapSurfaces, _light)) + { + _surShadowmapOld = __shadowmapSurfaces[? _light]; + } + + _surShadowmap = bbmod_surface_check( + _surShadowmapOld, _light.ShadowmapResolution, _light.ShadowmapResolution, surface_rgba8unorm, true); + + if (_surShadowmap != _surShadowmapOld) + { + __shadowmapSurfaces[? _light] = _surShadowmap; + } + + surface_set_target(_surShadowmap); + draw_clear(c_red); + matrix_set(matrix_view, _light.__getViewMatrix()); + matrix_set(matrix_projection, _light.__getProjMatrix()); + bbmod_shader_set_global_f(BBMOD_U_ZFAR, _shadowmapZFar); + var _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + bbmod_material_reset(); + surface_reset_target(); + } + + _light.NeedsUpdate = false; + } + + if (_light.Frameskip == infinity) + { + _light.__frameskipCurrent = -1; + } + else if (++_light.__frameskipCurrent > _light.Frameskip) + { + _light.__frameskipCurrent = 0; + } + }; + + /// @func __render_shadowmaps() /// /// @desc Renders a shadowmap. /// @@ -383,28 +589,19 @@ function BBMOD_BaseRenderer() constructor /// that yourself in the calling function if needed. /// /// @private - static __render_shadowmap = function () + static __render_shadowmaps = function () { - static _renderQueues = bbmod_render_queues_get(); - var _shadowCaster = undefined; var _shadowCasterIndex = -1; - var _shadowmapMatrix; - var _shadowmapZFar; - var _light; if (EnableShadows) { - _light = bbmod_light_directional_get(); + var _light = bbmod_light_directional_get(); if (_light != undefined - && _light.CastShadows - && _light.__getZFar != undefined - && _light.__getShadowmapMatrix != undefined) + && _light.CastShadows) { // Directional light _shadowCaster = _light; - _shadowmapMatrix = _light.__getShadowmapMatrix(); - _shadowmapZFar = _light.__getZFar(); } else { @@ -413,14 +610,10 @@ function BBMOD_BaseRenderer() constructor repeat (array_length(global.__bbmodPunctualLights)) { _light = global.__bbmodPunctualLights[i]; - if (_light.CastShadows - && _light.__getZFar != undefined - && _light.__getShadowmapMatrix != undefined) + if (_light.CastShadows) { _shadowCaster = _light; _shadowCasterIndex = i; - _shadowmapMatrix = _light.__getShadowmapMatrix(); - _shadowmapZFar = _light.__getZFar(); break; } ++i; @@ -430,39 +623,16 @@ function BBMOD_BaseRenderer() constructor if (_shadowCaster == undefined) { - if (surface_exists(__surShadowmap)) - { - surface_free(__surShadowmap); - __surShadowmap = -1; - } - // No shadow caster was found!!! bbmod_shader_unset_global(BBMOD_U_SHADOWMAP); bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_VS, 0.0); bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_PS, 0.0); + __gc_collect_shadowmaps(); return; } - bbmod_render_pass_set(BBMOD_ERenderPass.Shadows); - - __surShadowmap = bbmod_surface_check( - __surShadowmap, _light.ShadowmapResolution, _light.ShadowmapResolution, surface_rgba8unorm, true); - - surface_set_target(__surShadowmap); - draw_clear(c_red); - matrix_set(matrix_view, _light.__getViewMatrix()); - matrix_set(matrix_projection, _light.__getProjMatrix()); - bbmod_shader_set_global_f(BBMOD_U_ZFAR, _light.__getZFar()); - - var _rqi = 0; - repeat (array_length(_renderQueues)) - { - _renderQueues[_rqi++].submit(); - } - bbmod_material_reset(); - - surface_reset_target(); + __render_shadowmap_impl(_shadowCaster); - var _shadowmapTexture = surface_get_texture(__surShadowmap); + var _shadowmapTexture = surface_get_texture(__shadowmapSurfaces[? _shadowCaster]); bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_VS, 1.0); bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_PS, 1.0); bbmod_shader_set_global_sampler(BBMOD_U_SHADOWMAP, _shadowmapTexture); @@ -472,10 +642,12 @@ function BBMOD_BaseRenderer() constructor bbmod_shader_set_global_f2(BBMOD_U_SHADOWMAP_TEXEL, texture_get_texel_width(_shadowmapTexture), texture_get_texel_height(_shadowmapTexture)); - bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_AREA, _shadowmapZFar); - bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_NORMAL_OFFSET, ShadowmapNormalOffset); - bbmod_shader_set_global_matrix_array(BBMOD_U_SHADOWMAP_MATRIX, _shadowmapMatrix); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_AREA, _shadowCaster.__getZFar()); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_NORMAL_OFFSET_VS, ShadowmapNormalOffset); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_NORMAL_OFFSET_PS, ShadowmapNormalOffset); + bbmod_shader_set_global_matrix_array(BBMOD_U_SHADOWMAP_MATRIX, _shadowCaster.__getShadowmapMatrix()); bbmod_shader_set_global_f(BBMOD_U_SHADOW_CASTER_INDEX, _shadowCasterIndex); + __gc_collect_shadowmaps(); }; /// @func __render_reflection_probes() @@ -520,7 +692,7 @@ function BBMOD_BaseRenderer() constructor { var _enableShadows = EnableShadows; EnableShadows &= other.EnableShadows; // Temporarily modify renderer's EnableShadows - __render_shadowmap(); + __render_shadowmaps(); EnableShadows = _enableShadows; } @@ -537,7 +709,6 @@ function BBMOD_BaseRenderer() constructor } _cubemap.reset_target(); } - bbmod_material_reset(); // Prefilter and apply _cubemap.to_single_surface(); @@ -583,9 +754,9 @@ function BBMOD_BaseRenderer() constructor camera_set_view_size(_camera, _width, _height); camera_apply(_camera); - shader_set(__BBMOD_ShMixRGBM); - texture_set_stage(shader_get_sampler_index(__BBMOD_ShMixRGBM, "u_texTo"), _to); - shader_set_uniform_f(shader_get_uniform(__BBMOD_ShMixRGBM, "u_fFactor"), 1.0); + shader_set(BBMOD_ShMixRGBM); + texture_set_stage(shader_get_sampler_index(BBMOD_ShMixRGBM, "u_texTo"), _to); + shader_set_uniform_f(shader_get_uniform(BBMOD_ShMixRGBM, "u_fFactor"), 1.0); draw_surface(__surProbe2, 0, 0); shader_reset(); @@ -612,9 +783,9 @@ function BBMOD_BaseRenderer() constructor camera_set_view_size(_camera, _width, _height); camera_apply(_camera); - shader_set(__BBMOD_ShMixRGBM); - texture_set_stage(shader_get_sampler_index(__BBMOD_ShMixRGBM, "u_texTo"), _to); - shader_set_uniform_f(shader_get_uniform(__BBMOD_ShMixRGBM, "u_fFactor"), 0.1); + shader_set(BBMOD_ShMixRGBM); + texture_set_stage(shader_get_sampler_index(BBMOD_ShMixRGBM, "u_texTo"), _to); + shader_set_uniform_f(shader_get_uniform(BBMOD_ShMixRGBM, "u_fFactor"), 0.1); draw_surface(__surProbe2, 0, 0); shader_reset(); @@ -778,6 +949,30 @@ function BBMOD_BaseRenderer() constructor } }; + static __render_ssao = function (_surDepth, _projection) + { + if (EnableSSAO) + { + var _width = get_render_width() * SSAOScale; + var _height = get_render_height() * SSAOScale; + + __surSSAO = bbmod_surface_check(__surSSAO, _width, _height, surface_rgba8unorm, false); + __surWork = bbmod_surface_check(__surWork, _width, _height, surface_rgba8unorm, false); + + bbmod_ssao_draw(SSAORadius * SSAOScale, SSAOPower, SSAOAngleBias, + SSAODepthRange, __surSSAO, __surWork, _surDepth, _projection, + bbmod_camera_get_zfar(), SSAOSelfOcclusionBias, SSAOBlurDepthRange); + + bbmod_shader_set_global_sampler( + BBMOD_U_SSAO, surface_get_texture(__surSSAO)); + } + else + { + bbmod_shader_set_global_sampler( + BBMOD_U_SSAO, sprite_get_texture(BBMOD_SprWhite, 0)); + } + }; + /// @func render(_clearQueues=true) /// /// @desc Renders all added [renderables](./BBMOD_BaseRenderer.Renderables.html) @@ -822,18 +1017,18 @@ function BBMOD_BaseRenderer() constructor // // Shadow map // - __render_shadowmap(); + __render_shadowmaps(); //////////////////////////////////////////////////////////////////////// // - // Forward pass + // Background // bbmod_shader_set_global_f(BBMOD_U_ZFAR, bbmod_camera_get_zfar()); matrix_set(matrix_view, _view); matrix_set(matrix_projection, _projection); - bbmod_render_pass_set(BBMOD_ERenderPass.Forward); + bbmod_render_pass_set(BBMOD_ERenderPass.Background); var _rqi = 0; repeat (array_length(_renderQueues)) @@ -842,6 +1037,19 @@ function BBMOD_BaseRenderer() constructor } bbmod_material_reset(); + //////////////////////////////////////////////////////////////////////// + // + // Forward pass + // + bbmod_render_pass_set(BBMOD_ERenderPass.Forward); + + _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + bbmod_material_reset(); + //////////////////////////////////////////////////////////////////////// // // Alpha pass @@ -1026,11 +1234,6 @@ function BBMOD_BaseRenderer() constructor surface_free(__surGizmo); } - if (surface_exists(__surShadowmap)) - { - surface_free(__surShadowmap); - } - if (surface_exists(__surFinal)) { surface_free(__surFinal); @@ -1046,12 +1249,45 @@ function BBMOD_BaseRenderer() constructor surface_free(__surProbe2); } + if (surface_exists(__surSSAO)) + { + surface_free(__surSSAO); + } + + if (surface_exists(__surWork)) + { + surface_free(__surWork); + } + if (UseAppSurface) { application_surface_enable(false); application_surface_draw_enable(true); } + ds_list_destroy(__shadowmapLights); + ds_list_destroy(__shadowmapHealth); + + var _key = ds_map_find_first(__shadowmapSurfaces); + repeat (ds_map_size(__shadowmapSurfaces)) + { + var _surface = __shadowmapSurfaces[? _key]; + if (surface_exists(_surface)) + { + surface_free(_surface); + } + _key = ds_map_find_next(__shadowmapSurfaces, _key); + } + ds_map_destroy(__shadowmapSurfaces); + + _key = ds_map_find_first(__shadowmapCubes); + repeat (ds_map_size(__shadowmapCubes)) + { + __shadowmapCubes[? _key].destroy(); + _key = ds_map_find_next(__shadowmapCubes, _key); + } + ds_map_destroy(__shadowmapCubes); + return undefined; }; } diff --git a/BBMOD_GML/scripts/BBMOD_BaseShader/BBMOD_BaseShader.gml b/BBMOD_GML/scripts/BBMOD_BaseShader/BBMOD_BaseShader.gml index 47926e7e..68628835 100644 --- a/BBMOD_GML/scripts/BBMOD_BaseShader/BBMOD_BaseShader.gml +++ b/BBMOD_GML/scripts/BBMOD_BaseShader/BBMOD_BaseShader.gml @@ -27,12 +27,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @param {Struct.BBMOD_Vec2} _offset The texture offset. /// /// @return {Struct.BBMOD_Shader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_texture_offset} instead. static set_texture_offset = function (_offset) { gml_pragma("forceinline"); - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_TEXTURE_OFFSET), - _offset.X, _offset.Y); + bbmod_shader_set_texture_offset(shader_current(), _offset); return self; }; @@ -43,12 +43,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @param {Struct.BBMOD_Vec2} _scale The texture scale. /// /// @return {Struct.BBMOD_Shader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_texture_scale} instead. static set_texture_scale = function (_scale) { gml_pragma("forceinline"); - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_TEXTURE_SCALE), - _scale.X, _scale.Y); + bbmod_shader_set_texture_scale(shader_current(), _scale); return self; }; @@ -61,12 +61,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @return {Struct.BBMOD_Shader} Returns `self`. /// /// @see BBMOD_AnimationPlayer.get_transform + /// + /// @deprecated Please use {@link bbmod_shader_set_bones} instead. static set_bones = function (_bones) { gml_pragma("forceinline"); - shader_set_uniform_f_array( - shader_get_uniform(shader_current(), BBMOD_U_BONES), - _bones); + bbmod_shader_set_bones(shader_current(), _bones); return self; }; @@ -77,12 +77,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @param {Array} _data The dynamic batch data. /// /// @return {Struct.BBMOD_Shader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_batch_data} instead. static set_batch_data = function (_data) { gml_pragma("forceinline"); - shader_set_uniform_f_array( - shader_get_uniform(shader_current(), BBMOD_U_BATCH_DATA), - _data); + bbmod_shader_set_batch_data(shader_current(), _data); return self; }; @@ -93,12 +93,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @param {Real} _value The alpha test value. /// /// @return {Struct.BBMOD_Shader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_alpha_test} instead. static set_alpha_test = function (_value) { gml_pragma("forceinline"); - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_ALPHA_TEST), - _value); + bbmod_shader_set_alpha_test(shader_current(), _value); return self; }; @@ -110,13 +110,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// then the value set by {@link bbmod_camera_set_position} is used. /// /// @return {Struct.BBMOD_Shader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_cam_pos} instead. static set_cam_pos = function (_pos=undefined) { gml_pragma("forceinline"); - _pos ??= global.__bbmodCameraPosition; - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_CAM_POS), - _pos.X, _pos.Y, _pos.Z); + bbmod_shader_set_cam_pos(shader_current(), _pos); return self; }; @@ -128,12 +127,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// then the value set by {@link bbmod_camera_set_exposure} is used. /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_exposure} instead. static set_exposure = function (_value=undefined) { gml_pragma("forceinline"); - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_EXPOSURE), - _value ?? global.__bbmodCameraExposure); + bbmod_shader_set_exposure(shader_current(), _value); return self; }; @@ -145,16 +144,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// then the value set by {@link bbmod_set_instance_id} is used. /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_instance_id} instead. static set_instance_id = function (_id=undefined) { gml_pragma("forceinline"); - _id ??= global.__bbmodInstanceID; - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_INSTANCE_ID), - ((_id & $000000FF) >> 0) / 255, - ((_id & $0000FF00) >> 8) / 255, - ((_id & $00FF0000) >> 16) / 255, - ((_id & $FF000000) >> 24) / 255); + bbmod_shader_set_instance_id(shader_current(), _id); return self; }; @@ -165,12 +160,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @param {Real} [_index] The index of the current material. /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_material_index} instead. static set_material_index = function (_index) { gml_pragma("forceinline"); - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_MATERIAL_INDEX), - _index); + bbmod_shader_set_material_index(shader_current(), _index); return self; }; @@ -185,52 +180,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// the light is not enabled, then it is not passed. /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_ibl} instead. static set_ibl = function (_ibl=undefined) { gml_pragma("forceinline"); - - var _texture = pointer_null; - var _texel; - - _ibl ??= global.__bbmodImageBasedLight; - - if (_ibl != undefined - && _ibl.Enabled) - { - _texture = _ibl.Texture; - _texel = _ibl.Texel; - } - - if (global.__bbmodReflectionProbeTexture != pointer_null) - { - _texture = global.__bbmodReflectionProbeTexture; - _texel = texture_get_texel_height(_texture); - } - - var _shaderCurrent = shader_current(); - - if (_texture != pointer_null) - { - var _uIBL = shader_get_sampler_index(_shaderCurrent, BBMOD_U_IBL); - - texture_set_stage(_uIBL, _texture); - gpu_set_tex_mip_enable_ext(_uIBL, mip_off) - gpu_set_tex_filter_ext(_uIBL, true); - gpu_set_tex_repeat_ext(_uIBL, false); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_IBL_TEXEL), - _texel, _texel); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_IBL_ENABLE), - 1.0); - } - else - { - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_IBL_ENABLE), - 0.0); - } - + bbmod_shader_set_ibl(shader_current(), _ibl); return self; }; @@ -250,22 +205,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// {@link bbmod_light_ambient_set_dir} is used. /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_ambient_light} instead. static set_ambient_light = function (_up=undefined, _down=undefined, _dir=undefined) { gml_pragma("forceinline"); - _up ??= global.__bbmodAmbientLightUp; - _down ??= global.__bbmodAmbientLightDown; - _dir ??= global.__bbmodAmbientLightDirUp; - var _shaderCurrent = shader_current(); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_AMBIENT_UP), - _up.Red / 255.0, _up.Green / 255.0, _up.Blue / 255.0, _up.Alpha); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_AMBIENT_DOWN), - _down.Red / 255.0, _down.Green / 255.0, _down.Blue / 255.0, _down.Alpha); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_AMBIENT_DIR_UP), - _dir.X, _dir.Y, _dir.Z); + bbmod_shader_set_ambient_light(shader_current(), _up, _down, _dir); return self; }; @@ -281,30 +226,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// @return {Struct.BBMOD_BaseShader} Returns `self`. /// /// @see BBMOD_DirectionalLight + /// + /// @deprecated Please use {@link bbmod_shader_set_directional_light} instead. static set_directional_light = function (_light=undefined) { gml_pragma("forceinline"); - _light ??= global.__bbmodDirectionalLight; - var _shaderCurrent = shader_current(); - var _uLightDirectionalDir = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_DIRECTIONAL_DIR); - var _uLightDirectionalColor = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_DIRECTIONAL_COLOR); - if (_light != undefined && _light.Enabled) - { - var _direction = _light.Direction; - shader_set_uniform_f(_uLightDirectionalDir, - _direction.X, _direction.Y, _direction.Z); - var _color = _light.Color; - shader_set_uniform_f(_uLightDirectionalColor, - _color.Red / 255.0, - _color.Green / 255.0, - _color.Blue / 255.0, - _color.Alpha); - } - else - { - shader_set_uniform_f(_uLightDirectionalDir, 0.0, 0.0, -1.0); - shader_set_uniform_f(_uLightDirectionalColor, 0.0, 0.0, 0.0, 0.0); - } + bbmod_shader_set_directional_light(shader_current(), _light); return self; }; @@ -319,11 +246,11 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. /// - /// @deprecated Please use {@link set_punctual_lights} instead. + /// @deprecated Please use {@link bbmod_shader_set_punctual_lights} instead. static set_point_lights = function (_lights=undefined) { gml_pragma("forceinline"); - set_punctual_lights(_lights); + bbmod_shader_set_punctual_lights(shader_current(), _lights); return self; }; @@ -337,65 +264,12 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// {@link bbmod_light_punctual_add} are passed. Only enabled lights will be used! /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_punctual_lights} instead. static set_punctual_lights = function (_lights=undefined) { gml_pragma("forceinline"); - - _lights ??= global.__bbmodPunctualLights; - - var _renderPassMask = (1 << bbmod_render_pass_get()); - - var _indexA = 0; - var _indexMaxA = BBMOD_MAX_PUNCTUAL_LIGHTS * 8; - var _dataA = array_create(_indexMaxA, 0.0); - - var _indexB = 0; - var _indexMaxB = BBMOD_MAX_PUNCTUAL_LIGHTS * 6; - var _dataB = array_create(_indexMaxB, 0.0); - - var i = 0; - - repeat (array_length(_lights)) - { - var _light = _lights[i++]; - - if (_light.Enabled - && (_light.RenderPass & _renderPassMask) != 0) - { - _light.Position.ToArray(_dataA, _indexA); - _dataA[@ _indexA + 3] = _light.Range; - var _color = _light.Color; - _dataA[@ _indexA + 4] = _color.Red / 255.0; - _dataA[@ _indexA + 5] = _color.Green / 255.0; - _dataA[@ _indexA + 6] = _color.Blue / 255.0; - _dataA[@ _indexA + 7] = _color.Alpha; - _indexA += 8; - - if (_light[$ "AngleInner"] != undefined) // Ugh, but works! - { - _dataB[@ _indexB] = 1.0; // Is spot light - _dataB[@ _indexB + 1] = dcos(_light.AngleInner); - _dataB[@ _indexB + 2] = dcos(_light.AngleOuter); - _light.Direction.ToArray(_dataB, _indexB + 3); - } - _indexB += 6; - - if (_indexA >= _indexMaxA) - { - break; - } - } - } - - var _shaderCurrent = shader_current(); - - shader_set_uniform_f_array( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_PUNCTUAL_DATA_A), - _dataA); - shader_set_uniform_f_array( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_PUNCTUAL_DATA_B), - _dataB); - + bbmod_shader_set_punctual_lights(shader_current(), _lights); return self; }; @@ -414,46 +288,28 @@ function BBMOD_BaseShader(_shader, _vertexFormat) /// If `undefined`, then the value set by {@link bbmod_fog_set_end} is used. /// /// @return {Struct.BBMOD_BaseShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_fog} instead. static set_fog = function (_color=undefined, _intensity=undefined, _start=undefined, _end=undefined) { gml_pragma("forceinline"); - _color ??= global.__bbmodFogColor; - _intensity ??= global.__bbmodFogIntensity; - _start ??= global.__bbmodFogStart; - _end ??= global.__bbmodFogEnd; - var _rcpFogRange = 1.0 / (_end - _start); - var _shaderCurrent = shader_current(); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_FOG_COLOR), - _color.Red / 255.0, - _color.Green / 255.0, - _color.Blue / 255.0, - _color.Alpha); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_FOG_INTENSITY), - _intensity); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_FOG_START), - _start); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_FOG_RCP_RANGE), - _rcpFogRange); + bbmod_shader_set_fog(shader_current(), _color, _intensity, _start, _end); return self; }; static on_set = function () { gml_pragma("forceinline"); - set_cam_pos(); - set_exposure(); - set_ibl(); - set_ambient_light(); - set_directional_light(); - set_punctual_lights(); - set_fog(); - texture_set_stage( - shader_get_sampler_index(shader_current(), BBMOD_U_SSAO), - sprite_get_texture(BBMOD_SprWhite, 0)); + var _shaderCurrent = shader_current(); + bbmod_shader_set_cam_pos(_shaderCurrent); + bbmod_shader_set_exposure(_shaderCurrent); + bbmod_shader_set_ibl(_shaderCurrent); + bbmod_shader_set_ambient_light(_shaderCurrent); + bbmod_shader_set_directional_light(_shaderCurrent); + bbmod_shader_set_punctual_lights(_shaderCurrent); + bbmod_shader_set_fog(_shaderCurrent); + bbmod_shader_set_ssao(_shaderCurrent, sprite_get_texture(BBMOD_SprWhite, 0)); + bbmod_shader_set_hdr(_shaderCurrent, 0.0); }; /// @func set_material(_material) @@ -469,18 +325,11 @@ function BBMOD_BaseShader(_shader, _vertexFormat) { gml_pragma("forceinline"); var _shaderCurrent = shader_current(); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_BASE_OPACITY_MULTIPLIER), - _material.BaseOpacityMultiplier.Red / 255.0, - _material.BaseOpacityMultiplier.Green / 255.0, - _material.BaseOpacityMultiplier.Blue / 255.0, - _material.BaseOpacityMultiplier.Alpha); - set_alpha_test(_material.AlphaTest); - set_texture_offset(_material.TextureOffset); - set_texture_scale(_material.TextureScale); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_SHADOWMAP_BIAS), - _material.ShadowmapBias); + bbmod_shader_set_base_opacity_multiplier(_shaderCurrent, _material.BaseOpacityMultiplier); + bbmod_shader_set_alpha_test(_shaderCurrent, _material.AlphaTest); + bbmod_shader_set_texture_offset(_shaderCurrent, _material.TextureOffset); + bbmod_shader_set_texture_scale(_shaderCurrent, _material.TextureScale); + bbmod_shader_set_shadowmap_bias(_shaderCurrent, _material.ShadowmapBias); return self; }; } diff --git a/BBMOD_GML/scripts/BBMOD_Cubemap/BBMOD_Cubemap.gml b/BBMOD_GML/scripts/BBMOD_Cubemap/BBMOD_Cubemap.gml index eccb252d..0bf3e59c 100644 --- a/BBMOD_GML/scripts/BBMOD_Cubemap/BBMOD_Cubemap.gml +++ b/BBMOD_GML/scripts/BBMOD_Cubemap/BBMOD_Cubemap.gml @@ -197,9 +197,9 @@ function BBMOD_Cubemap(_resolution) constructor draw_clear_alpha(_clearColor, _clearAlpha); camera_set_view_size(__camera2D, Resolution, Resolution); camera_apply(__camera2D); - shader_set(__BBMOD_ShCubemapToOctahedron); + shader_set(BBMOD_ShCubemapToOctahedron); shader_set_uniform_f( - shader_get_uniform(__BBMOD_ShCubemapToOctahedron, "u_vTexel"), + shader_get_uniform(BBMOD_ShCubemapToOctahedron, "u_vTexel"), 1 / Resolution, 1 / Resolution); draw_surface_stretched(Surface, 0, 0, Resolution, Resolution); @@ -237,8 +237,8 @@ function BBMOD_Cubemap(_resolution) constructor camera_set_view_size(__camera2D, _width, _height); camera_apply(__camera2D); - shader_set(__BBMOD_ShPrefilterSpecular); - var _uRoughness = shader_get_uniform(__BBMOD_ShPrefilterSpecular, "u_fRoughness"); + shader_set(BBMOD_ShPrefilterSpecular); + var _uRoughness = shader_get_uniform(BBMOD_ShPrefilterSpecular, "u_fRoughness"); for (var i = 0; i <= 6; ++i) { shader_set_uniform_f(_uRoughness, i / 6); @@ -247,7 +247,7 @@ function BBMOD_Cubemap(_resolution) constructor } shader_reset(); - shader_set(__BBMOD_ShPrefilterDiffuse); + shader_set(BBMOD_ShPrefilterDiffuse); draw_surface(SurfaceOctahedron, _x, 0); _x += Resolution; shader_reset(); diff --git a/BBMOD_GML/scripts/BBMOD_DefaultLightmapShader/BBMOD_DefaultLightmapShader.gml b/BBMOD_GML/scripts/BBMOD_DefaultLightmapShader/BBMOD_DefaultLightmapShader.gml index fcaa6692..d0e82a8b 100644 --- a/BBMOD_GML/scripts/BBMOD_DefaultLightmapShader/BBMOD_DefaultLightmapShader.gml +++ b/BBMOD_GML/scripts/BBMOD_DefaultLightmapShader/BBMOD_DefaultLightmapShader.gml @@ -20,173 +20,28 @@ function BBMOD_DefaultLightmapShader(_shader, _vertexFormat) static set_ibl = function (_ibl=undefined) { gml_pragma("forceinline"); - - var _texture = pointer_null; - var _texel; - - _ibl ??= global.__bbmodImageBasedLight; - - if (_ibl != undefined - && _ibl.Enabled - && _ibl.AffectLightmaps) - { - _texture = _ibl.Texture; - _texel = _ibl.Texel; - } - - if (global.__bbmodReflectionProbeTexture != pointer_null) - { - _texture = global.__bbmodReflectionProbeTexture; - _texel = texture_get_texel_height(_texture); - } - - var _shaderCurrent = shader_current(); - - if (_texture != pointer_null) - { - var _uIBL = shader_get_sampler_index(_shaderCurrent, BBMOD_U_IBL); - - texture_set_stage(_uIBL, _texture); - gpu_set_tex_mip_enable_ext(_uIBL, mip_off) - gpu_set_tex_filter_ext(_uIBL, true); - gpu_set_tex_repeat_ext(_uIBL, false); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_IBL_TEXEL), - _texel, _texel); - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_IBL_ENABLE), - 1.0); - } - else - { - shader_set_uniform_f( - shader_get_uniform(_shaderCurrent, BBMOD_U_IBL_ENABLE), - 0.0); - } - + bbmod_shader_set_ibl(shader_current(), _ibl, true); return self; }; static set_ambient_light = function (_up=undefined, _down=undefined, _dir=undefined) { gml_pragma("forceinline"); - var _shaderCurrent = shader_current(); - var _uLightAmbientUp = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_AMBIENT_UP); - var _uLightAmbientDown = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_AMBIENT_DOWN); - var _uLightAmbientDirUp = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_AMBIENT_DIR_UP); - if (global.__bbmodAmbientAffectLightmap) - { - _up ??= global.__bbmodAmbientLightUp; - _down ??= global.__bbmodAmbientLightDown; - _dir ??= global.__bbmodAmbientLightDirUp; - shader_set_uniform_f( - _uLightAmbientUp, - _up.Red / 255.0, _up.Green / 255.0, _up.Blue / 255.0, _up.Alpha); - shader_set_uniform_f( - _uLightAmbientDown, - _down.Red / 255.0, _down.Green / 255.0, _down.Blue / 255.0, _down.Alpha); - shader_set_uniform_f( - _uLightAmbientDirUp, - _dir.X, _dir.Y, _dir.Z); - } - else - { - shader_set_uniform_f(_uLightAmbientUp, 0.0, 0.0, 0.0, 0.0); - shader_set_uniform_f(_uLightAmbientDown, 0.0, 0.0, 0.0, 0.0); - //shader_set_uniform_f(_uLightAmbientDirUp, 0.0, 0.0, 0.0); - } + bbmod_shader_set_ambient_light(shader_current(), _up, _down, _dir, true); return self; }; static set_directional_light = function (_light=undefined) { gml_pragma("forceinline"); - _light ??= global.__bbmodDirectionalLight; - var _shaderCurrent = shader_current(); - var _uLightDirectionalDir = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_DIRECTIONAL_DIR); - var _uLightDirectionalColor = shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_DIRECTIONAL_COLOR); - if (_light != undefined - && _light.Enabled - && _light.AffectLightmaps) - { - var _direction = _light.Direction; - shader_set_uniform_f(_uLightDirectionalDir, - _direction.X, _direction.Y, _direction.Z); - var _color = _light.Color; - shader_set_uniform_f(_uLightDirectionalColor, - _color.Red / 255.0, - _color.Green / 255.0, - _color.Blue / 255.0, - _color.Alpha); - } - else - { - shader_set_uniform_f(_uLightDirectionalDir, 0.0, 0.0, -1.0); - shader_set_uniform_f(_uLightDirectionalColor, 0.0, 0.0, 0.0, 0.0); - } + bbmod_shader_set_directional_light(shader_current(), _light, true); return self; }; static set_punctual_lights = function (_lights=undefined) { gml_pragma("forceinline"); - - _lights ??= global.__bbmodPunctualLights; - - var _renderPassMask = (1 << bbmod_render_pass_get()); - - var _indexA = 0; - var _indexMaxA = BBMOD_MAX_PUNCTUAL_LIGHTS * 8; - var _dataA = array_create(_indexMaxA, 0.0); - - var _indexB = 0; - var _indexMaxB = BBMOD_MAX_PUNCTUAL_LIGHTS * 6; - var _dataB = array_create(_indexMaxB, 0.0); - - var i = 0; - - repeat (array_length(_lights)) - { - var _light = _lights[i++]; - - if (_light.Enabled - && (_light.RenderPass & _renderPassMask) != 0 - && _light.AffectLightmaps) - { - _light.Position.ToArray(_dataA, _indexA); - _dataA[@ _indexA + 3] = _light.Range; - var _color = _light.Color; - _dataA[@ _indexA + 4] = _color.Red / 255.0; - _dataA[@ _indexA + 5] = _color.Green / 255.0; - _dataA[@ _indexA + 6] = _color.Blue / 255.0; - _dataA[@ _indexA + 7] = _color.Alpha; - _indexA += 8; - - if (_light[$ "AngleInner"] != undefined) // Ugh, but works! - { - _dataB[@ _indexB] = 1.0; // Is spot light - _dataB[@ _indexB + 1] = dcos(_light.AngleInner); - _dataB[@ _indexB + 2] = dcos(_light.AngleOuter); - _light.Direction.ToArray(_dataB, _indexB + 3); - } - _indexB += 6; - - if (_indexA >= _indexMaxA) - { - break; - } - } - } - - var _shaderCurrent = shader_current(); - - shader_set_uniform_f_array( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_PUNCTUAL_DATA_A), - _dataA); - shader_set_uniform_f_array( - shader_get_uniform(_shaderCurrent, BBMOD_U_LIGHT_PUNCTUAL_DATA_B), - _dataB); - + bbmod_shader_set_punctual_lights(shader_current(), _lights, true); return self; }; @@ -199,20 +54,19 @@ function BBMOD_DefaultLightmapShader(_shader, _vertexFormat) /// {@link bbmod_lightmap_set}. /// /// @return {Struct.BBMOD_DefaultLightmapShader} Returns `self`. + /// + /// @deprecated Please use {@link bbmod_shader_set_lightmap} instead. static set_lightmap = function (_texture=global.__bbmodLightmap) { gml_pragma("forceinline"); - var _uLightmap = shader_get_sampler_index(shader_current(), BBMOD_U_LIGHTMAP); - texture_set_stage(_uLightmap, _texture); - gpu_set_tex_mip_enable_ext(_uLightmap, mip_off); - gpu_set_tex_filter_ext(_uLightmap, true); + bbmod_shader_set_lightmap(shader_current(), _texture); return self; }; static on_set = function () { DefaultShader_on_set(); - set_lightmap(); + bbmod_shader_set_lightmap(shader_current()); return self; }; @@ -222,7 +76,7 @@ function BBMOD_DefaultLightmapShader(_shader, _vertexFormat) DefaultShader_set_material(_material); if (_material.Lightmap != undefined) { - set_lightmap(_material.Lightmap); + bbmod_shader_set_lightmap(shader_current(), _material.Lightmap); } return self; }; diff --git a/BBMOD_GML/scripts/BBMOD_DefaultRenderer/BBMOD_DefaultRenderer.gml b/BBMOD_GML/scripts/BBMOD_DefaultRenderer/BBMOD_DefaultRenderer.gml index f5d64b31..7b39e3db 100644 --- a/BBMOD_GML/scripts/BBMOD_DefaultRenderer/BBMOD_DefaultRenderer.gml +++ b/BBMOD_GML/scripts/BBMOD_DefaultRenderer/BBMOD_DefaultRenderer.gml @@ -4,11 +4,13 @@ /// /// @extends BBMOD_BaseRenderer /// -/// @desc A forward renderer. Implemented render passes are: +/// @desc A forward renderer with support for a small number of lights and only +/// a single shadow casting lights. Implemented render passes are: /// {@link BBMOD_ERenderPass.ReflectionCapture}, /// {@link BBMOD_ERenderPass.Id}, /// {@link BBMOD_ERenderPass.Shadows}, /// {@link BBMOD_ERenderPass.DepthOnly}, +/// {@link BBMOD_ERenderPass.Background}, /// {@link BBMOD_ERenderPass.Forward} and /// {@link BBMOD_ERenderPass.Alpha}. /// @@ -39,9 +41,7 @@ /// renderer = renderer.destroy(); /// ``` /// -/// @see BBMOD_IRenderable /// @see BBMOD_Camera - function BBMOD_DefaultRenderer() : BBMOD_BaseRenderer() constructor { @@ -59,45 +59,6 @@ function BBMOD_DefaultRenderer() /// @private __surDepthBuffer = -1; - /// @var {Bool} Enables screen-space ambient occlusion. This requires - /// the depth buffer. Defaults to `false`. Enabling this requires the - /// [SSAO submodule](./SSAOSubmodule.html)! - /// @see BBMOD_DefaultRenderer.EnableGBuffer - EnableSSAO = false; - - /// @var {Id.Surface} The SSAO surface. - /// @private - __surSSAO = -1; - - /// @var {Id.Surface} Surface used for blurring SSAO. - /// @private - __surWork = -1; - - /// @var {Real} Resolution multiplier for SSAO surface. Defaults to 1. - SSAOScale = 1.0; - - /// @var {Real} Screen-space radius of SSAO. Default value is 16. - SSAORadius = 16.0; - - /// @var {Real} Strength of the SSAO effect. Should be greater than 0. - /// Default value is 1. - SSAOPower = 1.0; - - /// @var {Real} SSAO angle bias in radians. Default value is 0.03. - SSAOAngleBias = 0.03; - - /// @var {Real} Maximum depth difference of SSAO samples. Samples farther - /// away from the origin than this will not contribute to the effect. - /// Default value is 10. - SSAODepthRange = 10.0; - - /// @var {Real} Defaults to 0.01. Increase to fix self-occlusion. - SSAOSelfOcclusionBias = 0.01; - - /// @var {Real} Maximum depth difference over which can be SSAO samples - /// blurred. Defaults to 2. - SSAOBlurDepthRange = 2.0; - static render = function (_clearQueues=true) { global.__bbmodRendererCurrent = self; @@ -135,7 +96,7 @@ function BBMOD_DefaultRenderer() // // Shadow map // - __render_shadowmap(); + __render_shadowmaps(); bbmod_shader_set_global_f(BBMOD_U_ZFAR, bbmod_camera_get_zfar()); @@ -166,32 +127,16 @@ function BBMOD_DefaultRenderer() //////////////////////////////////////////////////////////////////////// // - // Render SSAO + // SSAO // - if (EnableGBuffer && EnableSSAO) - { - var _width = _renderWidth * SSAOScale; - var _height = _renderHeight * SSAOScale; - - __surSSAO = bbmod_surface_check(__surSSAO, _width, _height, surface_rgba8unorm, false); - __surWork = bbmod_surface_check(__surWork, _width, _height, surface_rgba8unorm, false); - - bbmod_ssao_draw(SSAORadius * SSAOScale, SSAOPower, SSAOAngleBias, - SSAODepthRange, __surSSAO, __surWork, __surDepthBuffer, _projection, - bbmod_camera_get_zfar(), SSAOSelfOcclusionBias, SSAOBlurDepthRange); - - bbmod_shader_set_global_sampler( - BBMOD_U_SSAO, surface_get_texture(__surSSAO)); - } - else + if (EnableGBuffer) { - bbmod_shader_set_global_sampler( - BBMOD_U_SSAO, sprite_get_texture(BBMOD_SprWhite, 0)); + __render_ssao(__surDepthBuffer, _projection); } //////////////////////////////////////////////////////////////////////// // - // Forward pass + // Background // bbmod_shader_set_global_sampler(BBMOD_U_GBUFFER, EnableGBuffer ? surface_get_texture(__surDepthBuffer) @@ -200,6 +145,19 @@ function BBMOD_DefaultRenderer() matrix_set(matrix_view, _view); matrix_set(matrix_projection, _projection); + bbmod_render_pass_set(BBMOD_ERenderPass.Background); + + var _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + bbmod_material_reset(); + + //////////////////////////////////////////////////////////////////////// + // + // Forward pass + // bbmod_render_pass_set(BBMOD_ERenderPass.Forward); var _rqi = 0; @@ -247,16 +205,6 @@ function BBMOD_DefaultRenderer() surface_free(__surDepthBuffer); } - if (surface_exists(__surSSAO)) - { - surface_free(__surSSAO); - } - - if (surface_exists(__surWork)) - { - surface_free(__surWork); - } - return undefined; }; } diff --git a/BBMOD_GML/scripts/BBMOD_DefaultShader/BBMOD_DefaultShader.gml b/BBMOD_GML/scripts/BBMOD_DefaultShader/BBMOD_DefaultShader.gml index d0c70d6b..323becac 100644 --- a/BBMOD_GML/scripts/BBMOD_DefaultShader/BBMOD_DefaultShader.gml +++ b/BBMOD_GML/scripts/BBMOD_DefaultShader/BBMOD_DefaultShader.gml @@ -24,14 +24,12 @@ function BBMOD_DefaultShader(_shader, _vertexFormat) /// the RGB channels and smoothness in the A channel. /// /// @return {Struct.BBMOD_DefaultShader} Returns `self`. + /// + /// @obsolete Please use {@link bbmod_shader_set_normal_smoothness} instead. static set_normal_smoothness = function (_texture) { gml_pragma("forceinline"); - var _shaderCurrent = shader_current(); - var _uIsRoughness = shader_get_uniform(_shaderCurrent, BBMOD_U_IS_ROUGHNESS); - var _uNormalW = shader_get_sampler_index(_shaderCurrent, BBMOD_U_NORMAL_W); - shader_set_uniform_f(_uIsRoughness, 0.0); - texture_set_stage(_uNormalW, _texture); + bbmod_shader_set_normal_smoothness(shader_current(), _texture); return self; }; @@ -43,14 +41,13 @@ function BBMOD_DefaultShader(_shader, _vertexFormat) /// the RGB channels. /// /// @return {Struct.BBMOD_DefaultShader} Returns `self`. + /// + /// @obsolete Please use {@link bbmod_shader_set_specular_color} instead. static set_specular_color = function (_texture) { gml_pragma("forceinline"); - var _shaderCurrent = shader_current(); - var _uIsMetallic = shader_get_uniform(_shaderCurrent, BBMOD_U_IS_METALLIC); - var _uMaterial = shader_get_sampler_index(_shaderCurrent, BBMOD_U_MATERIAL); - shader_set_uniform_f(_uIsMetallic, 0.0); - texture_set_stage(_uMaterial, _texture); + bbmod_shader_set_specular_color(shader_current(), _texture); + return self; }; /// @func set_normal_roughness(_texture) @@ -61,14 +58,12 @@ function BBMOD_DefaultShader(_shader, _vertexFormat) /// the RGB channels and roughness in the A channel. /// /// @return {Struct.BBMOD_DefaultShader} Returns `self`. + /// + /// @obsolete Please use {@link bbmod_shader_set_normal_roughness} instead. static set_normal_roughness = function (_texture) { gml_pragma("forceinline"); - var _shaderCurrent = shader_current(); - var _uIsRoughness = shader_get_uniform(_shaderCurrent, BBMOD_U_IS_ROUGHNESS); - var _uNormalW = shader_get_sampler_index(_shaderCurrent, BBMOD_U_NORMAL_W); - shader_set_uniform_f(_uIsRoughness, 1.0); - texture_set_stage(_uNormalW, _texture); + bbmod_shader_set_normal_roughness(shader_current(), _texture); return self; }; @@ -80,14 +75,12 @@ function BBMOD_DefaultShader(_shader, _vertexFormat) /// R channel and ambient occlusion in the G channel. /// /// @return {Struct.BBMOD_DefaultShader} Returns `self`. + /// + /// @obsolete Please use {@link bbmod_shader_set_metallic_ao} instead. static set_metallic_ao = function (_texture) { gml_pragma("forceinline"); - var _shaderCurrent = shader_current(); - var _uIsMetallic = shader_get_uniform(_shaderCurrent, BBMOD_U_IS_METALLIC); - var _uMaterial = shader_get_sampler_index(_shaderCurrent, BBMOD_U_MATERIAL); - shader_set_uniform_f(_uIsMetallic, 1.0); - texture_set_stage(_uMaterial, _texture); + bbmod_shader_set_metallic_ao(shader_current(), _texture); return self; }; @@ -99,11 +92,12 @@ function BBMOD_DefaultShader(_shader, _vertexFormat) /// in the RGB channels and its intensity in the A channel. /// /// @return {Struct.BBMOD_DefaultShader} Returns `self`. + /// + /// @obsolete Please use {@link bbmod_shader_set_subsurface} instead. static set_subsurface = function (_texture) { gml_pragma("forceinline"); - var _uSubsurface = shader_get_sampler_index(shader_current(), BBMOD_U_SUBSURFACE); - texture_set_stage(_uSubsurface, _texture); + bbmod_shader_set_subsurface(shader_current(), _texture); return self; }; @@ -115,46 +109,50 @@ function BBMOD_DefaultShader(_shader, _vertexFormat) /// emissive color. /// /// @return {Struct.BBMOD_DefaultShader} Returns `self`. + /// + /// @obsolete Please use {@link bbmod_shader_set_emissive} instead. static set_emissive = function (_texture) { gml_pragma("forceinline"); - var _uEmissive = shader_get_sampler_index(shader_current(), BBMOD_U_EMISSIVE); - texture_set_stage(_uEmissive, _texture); + bbmod_shader_set_emissive(shader_current(), _texture); return self; }; static set_material = function (_material) { gml_pragma("forceinline"); + BaseShader_set_material(_material); + var _shaderCurrent = shader_current(); + // Normal smoothness/roughness if (_material.NormalSmoothness != undefined) { - set_normal_smoothness(_material.NormalSmoothness); + bbmod_shader_set_normal_smoothness(_shaderCurrent, _material.NormalSmoothness); } if (_material.NormalRoughness != undefined) { - set_normal_roughness(_material.NormalRoughness); + bbmod_shader_set_normal_roughness(_shaderCurrent, _material.NormalRoughness); } // Specular color/Metallic and AO if (_material.SpecularColor != undefined) { - set_specular_color(_material.SpecularColor); + bbmod_shader_set_specular_color(_shaderCurrent, _material.SpecularColor); } if (_material.MetallicAO != undefined) { - set_metallic_ao(_material.MetallicAO); + bbmod_shader_set_metallic_ao(_shaderCurrent, _material.MetallicAO); } // Subsurface - set_subsurface(_material.Subsurface); + bbmod_shader_set_subsurface(_shaderCurrent, _material.Subsurface); // Emissive - set_emissive(_material.Emissive); + bbmod_shader_set_emissive(_shaderCurrent, _material.Emissive); return self; }; diff --git a/BBMOD_GML/scripts/BBMOD_DefaultSpriteShader/BBMOD_DefaultSpriteShader.gml b/BBMOD_GML/scripts/BBMOD_DefaultSpriteShader/BBMOD_DefaultSpriteShader.gml index 64f5a36e..83b6d589 100644 --- a/BBMOD_GML/scripts/BBMOD_DefaultSpriteShader/BBMOD_DefaultSpriteShader.gml +++ b/BBMOD_GML/scripts/BBMOD_DefaultSpriteShader/BBMOD_DefaultSpriteShader.gml @@ -20,6 +20,7 @@ function BBMOD_DefaultSpriteShader(_shader, _vertexFormat) static set_material = function (_material) { gml_pragma("forceinline"); + DefaultShader_set_material(_material); var _shaderCurrent = shader_current(); @@ -27,22 +28,19 @@ function BBMOD_DefaultSpriteShader(_shader, _vertexFormat) var _texture = _material.BaseOpacity; if (_texture != pointer_null) { - var _uBaseOpacityUV = shader_get_uniform(_shaderCurrent, BBMOD_U_BASE_OPACITY_UV); - shader_set_uniform_f_array(_uBaseOpacityUV, texture_get_uvs(_texture)); + bbmod_shader_set_base_opacity_uv(_shaderCurrent, texture_get_uvs(_texture)); } _texture = _material.NormalSmoothness ?? _material.NormalRoughness; if (_texture != undefined) { - var _uNormalWUV = shader_get_uniform(_shaderCurrent, BBMOD_U_NORMAL_W_UV); - shader_set_uniform_f_array(_uNormalWUV, texture_get_uvs(_texture)); + bbmod_shader_set_normal_w_uv(_shaderCurrent, texture_get_uvs(_texture)); } _texture = _material.SpecularColor ?? _material.MetallicAO; if (_texture != undefined) { - var _uMaterialUV = shader_get_uniform(_shaderCurrent, BBMOD_U_MATERIAL_UV); - shader_set_uniform_f_array(_uMaterialUV, texture_get_uvs(_texture)); + bbmod_shader_set_normal_w_uv(_shaderCurrent, texture_get_uvs(_texture)); } return self; diff --git a/BBMOD_GML/scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.gml b/BBMOD_GML/scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.gml new file mode 100644 index 00000000..aac98f8e --- /dev/null +++ b/BBMOD_GML/scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.gml @@ -0,0 +1,633 @@ +/// @module DeferredRenderer + +/// @func BBMOD_DeferredRenderer() +/// +/// @extends BBMOD_BaseRenderer +/// +/// @desc A deferred renderer with support for unlimited number of shadow-casting +/// lights. Implemented render passes are: +/// {@link BBMOD_ERenderPass.ReflectionCapture}, +/// {@link BBMOD_ERenderPass.Id}, +/// {@link BBMOD_ERenderPass.Shadows}, +/// {@link BBMOD_ERenderPass.GBuffer}, +/// {@link BBMOD_ERenderPass.Background}, +/// {@link BBMOD_ERenderPass.Forward} and +/// {@link BBMOD_ERenderPass.Alpha}. +/// +/// @example +/// Following code is a typical use of the renderer. +/// ```gml +/// /// @desc Create event +/// renderer = new BBMOD_DeferredRenderer(); +/// renderer.UseAppSurface = true; +/// renderer.EnableShadows = true; +/// +/// camera = new BBMOD_Camera(); +/// camera.FollowObject = OPlayer; +/// +/// /// @desc Step event +/// camera.set_mouselook(true); +/// camera.update(delta_time); +/// renderer.update(delta_time); +/// +/// /// @desc Draw event +/// camera.apply(); +/// renderer.render(); +/// +/// /// @desc Post-Draw event +/// renderer.present(); +/// +/// /// @desc Clean Up event +/// renderer = renderer.destroy(); +/// ``` +/// +/// @note Deferred renderer requires multiple render targets and 16 bit floating +/// point texture format! You can use function {@link bbmod_deferred_renderer_is_supported} +/// to check whether the current platform meets all requirements. +/// +/// @see bbmod_deferred_renderer_is_supported +/// @see BBMOD_Camera +function BBMOD_DeferredRenderer() + : BBMOD_BaseRenderer() constructor +{ + static BaseRenderer_destroy = destroy; + static BaseRenderer_present = present; + + /// @var {Bool} + /// @private + __enableHDR = true; + + /// @var {Array} + /// @private + __surGBuffer = [ + // R | G | B | A + // -- | -- | -- | -- + -1, // Albedo.rgb | AO + -1, // Normal.xyz | Roughness + -1, // Depth 24bit | Metallic + // Emissive (using the L-buffer) + ]; + + /// @var {Id.Surface} + /// @private + __surLBuffer = -1; + + /// @var {Id.Surface} + /// @private + __surFinal = -1; + + /// @var {Real} + /// @private + __gBufferZFar = 1.0; + + /// @var {Id.Camera} + /// @private + __camera2D = camera_create(); + + /// @var {Struct.BBMOD_Model} + /// @private + static __sphere = new BBMOD_Model("Data/BBMOD/Models/Sphere.bbmod").freeze(); + + static __render_shadowmaps = function () + { + var _shadowCaster = undefined; + var _shadowCasterIndex = -1; + + if (EnableShadows) + { + // Directional light + var _light = bbmod_light_directional_get(); + if (_light != undefined + && _light.CastShadows) + { + __render_shadowmap_impl(_light); + _shadowCaster = _light; + } + + // Punctual lights + var i = 0; + repeat (array_length(global.__bbmodPunctualLights)) + { + _light = global.__bbmodPunctualLights[i]; + if (_light.CastShadows) + { + __render_shadowmap_impl(_light); + if (_shadowCaster == undefined) + { + _shadowCaster = _light; + _shadowCasterIndex = i; + } + } + ++i; + } + } + + if (_shadowCaster == undefined) + { + bbmod_shader_unset_global(BBMOD_U_SHADOWMAP); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_VS, 0.0); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_PS, 0.0); + __gc_collect_shadowmaps(); + return; + } + + var _shadowmapTexture = surface_get_texture(__shadowmapSurfaces[? _shadowCaster]); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_VS, 1.0); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_ENABLE_PS, 1.0); + bbmod_shader_set_global_sampler(BBMOD_U_SHADOWMAP, _shadowmapTexture); + bbmod_shader_set_global_sampler_mip_enable(BBMOD_U_SHADOWMAP, true); + bbmod_shader_set_global_sampler_filter(BBMOD_U_SHADOWMAP, true); + bbmod_shader_set_global_sampler_repeat(BBMOD_U_SHADOWMAP, false); + bbmod_shader_set_global_f2(BBMOD_U_SHADOWMAP_TEXEL, + texture_get_texel_width(_shadowmapTexture), + texture_get_texel_height(_shadowmapTexture)); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_AREA, _shadowCaster.__getZFar()); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_NORMAL_OFFSET_VS, ShadowmapNormalOffset); + bbmod_shader_set_global_f(BBMOD_U_SHADOWMAP_NORMAL_OFFSET_PS, ShadowmapNormalOffset); + bbmod_shader_set_global_matrix_array(BBMOD_U_SHADOWMAP_MATRIX, _shadowCaster.__getShadowmapMatrix()); + bbmod_shader_set_global_f(BBMOD_U_SHADOW_CASTER_INDEX, _shadowCasterIndex); + __gc_collect_shadowmaps(); + }; + + static render = function (_clearQueues=true) + { + global.__bbmodRendererCurrent = self; + + static _renderQueues = bbmod_render_queues_get(); + + var _world = matrix_get(matrix_world); + var _view = matrix_get(matrix_view); + var _projection = matrix_get(matrix_projection); + var _renderWidth = get_render_width(); + var _renderHeight = get_render_height(); + + camera_set_view_size(__camera2D, _renderWidth, _renderHeight); + + var i = 0; + repeat (array_length(Renderables)) + { + with (Renderables[i++]) + { + render(); + } + } + + //////////////////////////////////////////////////////////////////////// + // + // Reflection probes + // + __render_reflection_probes(); + + //////////////////////////////////////////////////////////////////////// + // + // Edit mode + // + __render_gizmo_and_instance_ids(); + + //////////////////////////////////////////////////////////////////////// + // + // Shadow map + // + __render_shadowmaps(); + + __gBufferZFar = bbmod_camera_get_zfar(); + var _hdr = (__enableHDR && bbmod_hdr_is_supported()); + + bbmod_shader_set_global_f(BBMOD_U_ZFAR, __gBufferZFar); + bbmod_shader_set_global_f(BBMOD_U_HDR, _hdr ? 1.0 : 0.0); + + //////////////////////////////////////////////////////////////////////// + // + // G-buffer pass + // + bbmod_shader_set_global_sampler("u_texBestFitNormalLUT", sprite_get_texture(BBMOD_SprBestFitNormalLUT, 0)); + bbmod_shader_set_global_sampler_filter("u_texBestFitNormalLUT", false); + bbmod_shader_set_global_sampler_mip_enable("u_texBestFitNormalLUT", false); + bbmod_shader_set_global_sampler_repeat("u_texBestFitNormalLUT", false); + + __surGBuffer[@ 0] = bbmod_surface_check(__surGBuffer[0], _renderWidth, _renderHeight, surface_rgba8unorm, false); + __surGBuffer[@ 1] = bbmod_surface_check(__surGBuffer[1], _renderWidth, _renderHeight, surface_rgba8unorm, false); + __surGBuffer[@ 2] = bbmod_surface_check(__surGBuffer[2], _renderWidth, _renderHeight, surface_rgba8unorm, false); + __surLBuffer = bbmod_surface_check(__surLBuffer, _renderWidth, _renderHeight, _hdr ? surface_rgba16float : surface_rgba8unorm, false); + __surFinal = bbmod_surface_check(__surFinal, _renderWidth, _renderHeight, _hdr ? surface_rgba16float : surface_rgba8unorm, true); + + surface_set_target_ext(0, __surFinal); + surface_set_target_ext(1, __surGBuffer[1]); + surface_set_target_ext(2, __surGBuffer[2]); + draw_clear_alpha(c_black, 0.0); + surface_reset_target(); + + surface_set_target(__surLBuffer); + draw_clear(c_black); + surface_reset_target(); + + surface_set_target_ext(0, __surFinal); + surface_set_target_ext(1, __surGBuffer[1]); + surface_set_target_ext(2, __surGBuffer[2]); + surface_set_target_ext(3, __surLBuffer); + + gpu_push_state(); + gpu_set_state(bbmod_gpu_get_default_state()); + gpu_set_blendenable(false); + + matrix_set(matrix_world, _world); + matrix_set(matrix_view, _view); + matrix_set(matrix_projection, _projection); + + bbmod_render_pass_set(BBMOD_ERenderPass.GBuffer); + var _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + bbmod_material_reset(); + + gpu_pop_state(); + surface_reset_target(); + + bbmod_shader_unset_global("u_texBestFitNormalLUT"); + + //////////////////////////////////////////////////////////////////////// + // + // Clone base color surface + // + surface_set_target(__surGBuffer[0]); + gpu_push_state(); + gpu_set_state(bbmod_gpu_get_default_state()); + draw_clear_alpha(c_black, 0.0); + gpu_set_blendenable(false); + matrix_set(matrix_world, matrix_build_identity()); + draw_surface(__surFinal, 0, 0); + matrix_set(matrix_world, _world); + gpu_pop_state(); + surface_reset_target(); + + //////////////////////////////////////////////////////////////////////// + // + // SSAO + // + __render_ssao(__surGBuffer[2], _projection); + + //////////////////////////////////////////////////////////////////////// + // + // Lighting pass + // + surface_set_target(__surLBuffer); + + var _viewInverse = (new BBMOD_Matrix(_view)).Inverse().Raw; + var _tanAspect = __bbmod_matrix_proj_get_tanaspect(_projection); + + //////////////////////////////////////////////////////////////////////// + // Fullscreen + gpu_push_state(); + gpu_set_blendmode(bm_add); + camera_apply(__camera2D); + matrix_set(matrix_world, matrix_build_identity()); + var _shader = BBMOD_ShDeferredFullscreen; + shader_set(_shader); + __bbmod_shader_set_globals(_shader); + texture_set_stage(shader_get_sampler_index(_shader, "u_texGB1"), surface_get_texture(__surGBuffer[1])); + texture_set_stage(shader_get_sampler_index(_shader, "u_texGB2"), surface_get_texture(__surGBuffer[2])); + shader_set_uniform_matrix_array(shader_get_uniform(_shader, "u_mView"), _view); + shader_set_uniform_matrix_array(shader_get_uniform(_shader, "u_mViewInverse"), _viewInverse); + shader_set_uniform_matrix_array(shader_get_uniform(_shader, "u_mProjection"), _projection); + shader_set_uniform_f_array(shader_get_uniform(_shader, "u_vTanAspect"), _tanAspect); + bbmod_shader_set_cam_pos(_shader); + bbmod_shader_set_exposure(_shader); + bbmod_shader_set_ibl(_shader); + bbmod_shader_set_ambient_light(_shader); + bbmod_shader_set_directional_light(_shader); + draw_surface(__surGBuffer[0], 0, 0); + shader_reset(); + gpu_pop_state(); + + //////////////////////////////////////////////////////////////////////// + // Punctual lights + camera_apply(__camera2D); + matrix_set(matrix_world, matrix_build_identity()); + + _shader = BBMOD_ShDeferredPunctual; + shader_set(_shader); + __bbmod_shader_set_globals(_shader); + texture_set_stage(shader_get_sampler_index(_shader, "u_texGB1"), surface_get_texture(__surGBuffer[1])); + texture_set_stage(shader_get_sampler_index(_shader, "u_texGB2"), surface_get_texture(__surGBuffer[2])); + shader_set_uniform_matrix_array(shader_get_uniform(_shader, "u_mView"), _view); + shader_set_uniform_matrix_array(shader_get_uniform(_shader, "u_mViewInverse"), _viewInverse); + shader_set_uniform_matrix_array(shader_get_uniform(_shader, "u_mProjection"), _projection); + shader_set_uniform_f_array(shader_get_uniform(_shader, "u_vTanAspect"), _tanAspect); + + bbmod_shader_set_cam_pos(_shader); + bbmod_shader_set_exposure(_shader); + + var _uLightPosition = shader_get_uniform(_shader, "bbmod_LightPosition"); + var _uLightRange = shader_get_uniform(_shader, "bbmod_LightRange"); + var _uLightColor = shader_get_uniform(_shader, "bbmod_LightColor"); + var _uLightIsSpot = shader_get_uniform(_shader, "bbmod_LightIsSpot"); + var _uLightDirection = shader_get_uniform(_shader, "bbmod_LightDirection"); + var _uLightInner = shader_get_uniform(_shader, "bbmod_LightInner"); + var _uLightOuter = shader_get_uniform(_shader, "bbmod_LightOuter"); + var _uShadowmapEnablePS = shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_ENABLE_PS); + var _uShadowmap = shader_get_sampler_index(_shader, BBMOD_U_SHADOWMAP); + var _uShadowmapTexel = shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_TEXEL); + var _uShadowmapArea = shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_AREA); + var _uShadowmapNormalOffsetPS = shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_NORMAL_OFFSET_PS); + var _uShadowmapMatrix = shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_MATRIX); + var _uShadowmapBias = shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_BIAS); + var _sphere = __sphere.Meshes[0].VertexBuffer; + var _texGB0 = surface_get_texture(__surGBuffer[0]); + + matrix_set(matrix_view, _view); + matrix_set(matrix_projection, _projection); + + gpu_push_state(); + gpu_set_state(bbmod_gpu_get_default_state()); + gpu_set_blendmode(bm_add); + gpu_set_zwriteenable(false); + gpu_set_ztestenable(false); + gpu_set_cullmode(cull_clockwise); + + for (var i = array_length(global.__bbmodPunctualLights) - 1; i >= 0; --i) + { + with (global.__bbmodPunctualLights[i]) + { + if (!Enabled) + { + continue; + } + matrix_set(matrix_world, matrix_build( + Position.X, Position.Y, Position.Z, + 0, 0, 0, + Range, Range, Range + )); + shader_set_uniform_f(_uLightPosition, Position.X, Position.Y, Position.Z); + shader_set_uniform_f(_uLightRange, Range); + shader_set_uniform_f(_uLightColor, + Color.Red / 255.0, + Color.Green / 255.0, + Color.Blue / 255.0, + Color.Alpha + ); + if (is_instanceof(self, BBMOD_SpotLight)) + { + shader_set_uniform_f(_uLightIsSpot, 1.0); + shader_set_uniform_f(_uLightDirection, Direction.X, Direction.Y, Direction.Z); + shader_set_uniform_f(_uLightInner, dcos(AngleInner)); + shader_set_uniform_f(_uLightOuter, dcos(AngleOuter)); + + if (CastShadows) + { + var _shadowmapMatrix = __getShadowmapMatrix(); + var _shadowmapZFar = __getZFar(); + var _shadowmapSurface = other.__shadowmapSurfaces[? self]; + if (surface_exists(_shadowmapSurface)) + { + var _shadowmapTexture = surface_get_texture(_shadowmapSurface); + shader_set_uniform_f(_uShadowmapEnablePS, 1.0); + texture_set_stage(_uShadowmap, _shadowmapTexture); + gpu_set_tex_mip_enable_ext(_uShadowmap, true); + gpu_set_tex_filter_ext(_uShadowmap, true); + gpu_set_tex_repeat_ext(_uShadowmap, false); + shader_set_uniform_f(_uShadowmapTexel, + texture_get_texel_width(_shadowmapTexture), + texture_get_texel_height(_shadowmapTexture)); + shader_set_uniform_f(_uShadowmapArea, _shadowmapZFar); + shader_set_uniform_f(_uShadowmapNormalOffsetPS, other.ShadowmapNormalOffset); + shader_set_uniform_f(_uShadowmapBias, 0.0); + shader_set_uniform_matrix_array(_uShadowmapMatrix, _shadowmapMatrix); + } + else + { + shader_set_uniform_f(_uShadowmapEnablePS, 0.0); + } + } + else + { + shader_set_uniform_f(_uShadowmapEnablePS, 0.0); + } + } + else + { + shader_set_uniform_f(_uLightIsSpot, 0.0); + if (CastShadows) + { + var _shadowmapZFar = __getZFar(); + var _shadowmapSurface = other.__shadowmapSurfaces[? self]; + if (surface_exists(_shadowmapSurface)) + { + var _shadowmapTexture = surface_get_texture(_shadowmapSurface); + shader_set_uniform_f(_uShadowmapEnablePS, 1.0); + texture_set_stage(_uShadowmap, _shadowmapTexture); + gpu_set_tex_mip_enable_ext(_uShadowmap, true); + gpu_set_tex_filter_ext(_uShadowmap, true); + gpu_set_tex_repeat_ext(_uShadowmap, false); + shader_set_uniform_f(_uShadowmapTexel, + texture_get_texel_width(_shadowmapTexture), + texture_get_texel_height(_shadowmapTexture)); + shader_set_uniform_f(_uShadowmapArea, _shadowmapZFar); + shader_set_uniform_f(_uShadowmapNormalOffsetPS, other.ShadowmapNormalOffset); + shader_set_uniform_f(_uShadowmapBias, 0.0); + } + else + { + shader_set_uniform_f(_uShadowmapEnablePS, 0.0); + } + } + else + { + shader_set_uniform_f(_uShadowmapEnablePS, 0.0); + } + } + vertex_submit(_sphere, pr_trianglelist, _texGB0); + } + } + + matrix_set(matrix_world, _world); + + gpu_pop_state(); + shader_reset(); + surface_reset_target(); + + //////////////////////////////////////////////////////////////////////// + // + // Combine + // + surface_set_target(__surFinal); + + bbmod_shader_set_global_sampler(BBMOD_U_GBUFFER, surface_get_texture(__surGBuffer[2])); + + gpu_push_state(); + gpu_set_state(bbmod_gpu_get_default_state()); + gpu_set_blendenable(false); + gpu_set_zwriteenable(false); + gpu_set_ztestenable(false); + matrix_set(matrix_world, matrix_build_identity()); + camera_apply(__camera2D); + draw_rectangle_color(0, 0, _renderWidth, _renderHeight, c_black, c_black, c_black, c_black, false); + gpu_pop_state(); + + bbmod_render_pass_set(BBMOD_ERenderPass.Background); + matrix_set(matrix_world, _world); + matrix_set(matrix_view, _view); + matrix_set(matrix_projection, _projection); + _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + bbmod_material_reset(); + + gpu_push_state(); + gpu_set_state(bbmod_gpu_get_default_state()); + gpu_set_blendmode_ext_sepalpha(bm_src_alpha, bm_inv_src_alpha, bm_one, bm_inv_src_alpha); + gpu_set_zwriteenable(false); + gpu_set_ztestenable(false); + matrix_set(matrix_world, matrix_build_identity()); + camera_apply(__camera2D); + shader_set(BBMOD_ShFogAndDepthMask); + shader_set_uniform_f(shader_get_uniform(BBMOD_ShFogAndDepthMask, BBMOD_U_ZFAR), __gBufferZFar); + bbmod_shader_set_fog(BBMOD_ShFogAndDepthMask); + bbmod_shader_set_ambient_light(BBMOD_ShFogAndDepthMask); + bbmod_shader_set_directional_light(BBMOD_ShFogAndDepthMask); + texture_set_stage(shader_get_sampler_index(BBMOD_ShFogAndDepthMask, "u_texDepth"), surface_get_texture(__surGBuffer[2])); + draw_surface(__surLBuffer, 0, 0); + shader_reset(); + gpu_pop_state(); + + gpu_push_state(); + gpu_set_colorwriteenable(true, true, true, false); + matrix_set(matrix_world, _world); + matrix_set(matrix_view, _view); + matrix_set(matrix_projection, _projection); + + bbmod_render_pass_set(BBMOD_ERenderPass.Forward); + _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + //bbmod_material_reset(); + + bbmod_render_pass_set(BBMOD_ERenderPass.Alpha); + _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].submit(); + } + bbmod_material_reset(); + + gpu_pop_state(); + surface_reset_target(); + + //////////////////////////////////////////////////////////////////////// + // + // Clear queues + // + if (_clearQueues) + { + _rqi = 0; + repeat (array_length(_renderQueues)) + { + _renderQueues[_rqi++].clear(); + } + } + + //////////////////////////////////////////////////////////////////////// + // + // Blit + // + camera_apply(__camera2D); + matrix_set(matrix_world, matrix_build_identity()); + if (_hdr) + { + shader_set(BBMOD_ShHDRToSDR); + shader_set_uniform_f(shader_get_uniform(BBMOD_ShHDRToSDR, BBMOD_U_EXPOSURE), global.__bbmodCameraExposure); + } + draw_surface(__surFinal, 0, 0); + if (_hdr) + { + shader_reset(); + } + matrix_set(matrix_world, _world); + matrix_set(matrix_view, _view); + matrix_set(matrix_projection, _projection); + + //////////////////////////////////////////////////////////////////////// + + // Reset render pass back to Forward at the end! + bbmod_render_pass_set(BBMOD_ERenderPass.Forward); + + // Unset in case it gets destroyed when the room changes etc. + bbmod_shader_unset_global(BBMOD_U_SHADOWMAP); + bbmod_shader_unset_global(BBMOD_U_SSAO); + bbmod_shader_unset_global(BBMOD_U_GBUFFER); + bbmod_shader_set_global_f(BBMOD_U_HDR, 0.0); + + matrix_set(matrix_world, _world); + return self; + }; + + static present = function () + { + BaseRenderer_present(); + + //var _s = 1/6; + //var _w = get_width() * _s; + //var _h = get_height() * _s; + //var _x = X; + //var _y = Y; + + //for (var i = 0; i < array_length(__surGBuffer); ++i) + //{ + // shader_set(BBMOD_ShGBufferExtractRGB); + // draw_surface_stretched(__surGBuffer[i], _x, _y, _w, _h); _y += _h; + // shader_reset(); + + // shader_set(BBMOD_ShGBufferExtractA); + // draw_surface_stretched(__surGBuffer[i], _x, _y, _w, _h); _y += _h; + // shader_reset(); + //} + + return self; + }; + + static destroy = function () + { + BaseRenderer_destroy(); + + for (var i = array_length(__surGBuffer) - 1; i >= 0; --i) + { + if (surface_exists(__surGBuffer[i])) + { + surface_free(__surGBuffer[i]); + } + } + + if (surface_exists(__surLBuffer)) + { + surface_free(__surLBuffer); + } + + if (surface_exists(__surFinal)) + { + surface_free(__surFinal); + } + + camera_destroy(__camera2D); + + return undefined; + }; +} + +/// @func bbmod_deferred_renderer_is_supported() +/// +/// @desc Checks whether deferred renderer is supported. +/// +/// @return {Bool} Returns `true` if deferred renderer is supported. +/// +/// @see BBMOD_DeferredRenderer +function bbmod_deferred_renderer_is_supported() +{ + gml_pragma("forceinline"); + static _isSupported = (bbmod_mrt_is_supported() && bbmod_hdr_is_supported()); + return _isSupported; +} diff --git a/BBMOD_GML/scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.yy b/BBMOD_GML/scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.yy new file mode 100644 index 00000000..7e9d0e0b --- /dev/null +++ b/BBMOD_GML/scripts/BBMOD_DeferredRenderer/BBMOD_DeferredRenderer.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "BBMOD_DeferredRenderer", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "DeferredRenderer", + "path": "folders/BBMOD/DeferredRenderer.yy", + }, +} \ No newline at end of file diff --git a/BBMOD_GML/scripts/BBMOD_Light/BBMOD_Light.gml b/BBMOD_GML/scripts/BBMOD_Light/BBMOD_Light.gml index 586c440b..ec96145f 100644 --- a/BBMOD_GML/scripts/BBMOD_Light/BBMOD_Light.gml +++ b/BBMOD_GML/scripts/BBMOD_Light/BBMOD_Light.gml @@ -24,6 +24,7 @@ function BBMOD_Light() constructor /// /// @see BBMOD_ERenderPass RenderPass = (1 << BBMOD_ERenderPass.Forward) + | (1 << BBMOD_ERenderPass.Alpha) | (1 << BBMOD_ERenderPass.ReflectionCapture); /// @var {Struct.BBMOD_Vec3} The position of the light. @@ -41,6 +42,25 @@ function BBMOD_Light() constructor /// Defaults to 512. ShadowmapResolution = 512; + /// @var {Real} Number of frames to skip between individual updates of the + /// light's shadowmap. Default value is 0, which means no frame skipping. + Frameskip = 0; + + /// @var {Real} + /// @private + __frameskipCurrent = 0; + + /// @var {Bool} If `true` then the light's shadowmap is captured only once + /// or when requested via setting the {@link BBMOD_Light.NeedsUpdate} property + /// to `true`. + Static = false; + + /// @var {Bool} If `true` and the light is static, its shadowmap needs to be + /// updated. + /// @note This is automatically reset to `false` when the shadowmap is updated. + /// @see BBMOD_Light.Static + NeedsUpdate = true; + /// @var {Function} /// @private __getZFar = undefined; diff --git a/BBMOD_GML/scripts/BBMOD_Material/BBMOD_Material.gml b/BBMOD_GML/scripts/BBMOD_Material/BBMOD_Material.gml index 683b1283..99ecbcd8 100644 --- a/BBMOD_GML/scripts/BBMOD_Material/BBMOD_Material.gml +++ b/BBMOD_GML/scripts/BBMOD_Material/BBMOD_Material.gml @@ -616,7 +616,11 @@ function BBMOD_Material(_shader=undefined) if (global.__bbmodMaterialCurrent != self) { // TODO: GPU settings override per render pass! - var _isShadows = (bbmod_render_pass_get() == BBMOD_ERenderPass.Shadows); + var _renderPass = bbmod_render_pass_get(); + var _disableBlending = (_renderPass == BBMOD_ERenderPass.Shadows + || _renderPass == BBMOD_ERenderPass.DepthOnly + || _renderPass == BBMOD_ERenderPass.GBuffer + || _renderPass == BBMOD_ERenderPass.Id); if (global.__bbmodMaterialCurrent != undefined) { @@ -635,11 +639,11 @@ function BBMOD_Material(_shader=undefined) _shaderChanged = false; } - gpu_set_blendmode(_isShadows ? bm_normal : BlendMode); - gpu_set_blendenable(_isShadows ? false : AlphaBlend); + gpu_set_blendmode(_disableBlending ? bm_normal : BlendMode); + gpu_set_blendenable(_disableBlending ? false : AlphaBlend); gpu_set_cullmode(Culling); - gpu_set_zwriteenable(_isShadows ? true : ZWrite); - gpu_set_ztestenable(_isShadows ? true : ZTest); + gpu_set_zwriteenable(/*_disableBlending ? true : */ZWrite); + gpu_set_ztestenable(/*_disableBlending ? true : */ZTest); gpu_set_zfunc(ZFunc); gpu_set_tex_mip_enable(Mipmapping); gpu_set_tex_mip_bias(MipBias); diff --git a/BBMOD_GML/scripts/BBMOD_MaterialPropertyBlock/BBMOD_MaterialPropertyBlock.gml b/BBMOD_GML/scripts/BBMOD_MaterialPropertyBlock/BBMOD_MaterialPropertyBlock.gml index 8caf2122..c18bfbe3 100644 --- a/BBMOD_GML/scripts/BBMOD_MaterialPropertyBlock/BBMOD_MaterialPropertyBlock.gml +++ b/BBMOD_GML/scripts/BBMOD_MaterialPropertyBlock/BBMOD_MaterialPropertyBlock.gml @@ -34,7 +34,6 @@ global.__bbmodMaterialProps = undefined; /// bbmod_material_props_reset(); /// /// // Note: This works with method submit too, e.g.: -/// //bbmod_material_reset(); /// //bbmod_material_props_set(materialProps); /// //model.submit(); /// //bbmod_material_props_reset(); diff --git a/BBMOD_GML/scripts/BBMOD_Model/BBMOD_Model.gml b/BBMOD_GML/scripts/BBMOD_Model/BBMOD_Model.gml index 6b8b634d..158ee3f1 100644 --- a/BBMOD_GML/scripts/BBMOD_Model/BBMOD_Model.gml +++ b/BBMOD_GML/scripts/BBMOD_Model/BBMOD_Model.gml @@ -674,7 +674,6 @@ function BBMOD_Model(_file=undefined, _sha1=undefined) /// /// @example /// ```gml - /// bbmod_material_reset(); /// // Render a terrain model (does not have animation data) /// modTerrain.submit([mat_grass]); /// // Render a character model (animated by animationPlayer) diff --git a/BBMOD_GML/scripts/BBMOD_PointLight/BBMOD_PointLight.gml b/BBMOD_GML/scripts/BBMOD_PointLight/BBMOD_PointLight.gml index 2aa9bece..844d03d7 100644 --- a/BBMOD_GML/scripts/BBMOD_PointLight/BBMOD_PointLight.gml +++ b/BBMOD_GML/scripts/BBMOD_PointLight/BBMOD_PointLight.gml @@ -14,6 +14,13 @@ function BBMOD_PointLight(_color=BBMOD_C_WHITE, _position=undefined, _range=1.0) : BBMOD_PunctualLight(_color, _position, _range) constructor { + __getShadowmapMatrix = __get_shadowmap_matrix; + + static __get_shadowmap_matrix = function () + { + gml_pragma("forceinline"); + return matrix_build_identity(); + }; } /// @func bbmod_light_point_add(_light) diff --git a/BBMOD_GML/scripts/BBMOD_PunctualLight/BBMOD_PunctualLight.gml b/BBMOD_GML/scripts/BBMOD_PunctualLight/BBMOD_PunctualLight.gml index ac90f6d3..0550470a 100644 --- a/BBMOD_GML/scripts/BBMOD_PunctualLight/BBMOD_PunctualLight.gml +++ b/BBMOD_GML/scripts/BBMOD_PunctualLight/BBMOD_PunctualLight.gml @@ -36,6 +36,14 @@ function BBMOD_PunctualLight(_color=BBMOD_C_WHITE, _position=undefined, _range=1 /// @var {Real} The range of the light. Range = _range; + + __getZFar = __get_shadowmap_zfar; + + static __get_shadowmap_zfar = function () + { + gml_pragma("forceinline"); + return Range; + }; } /// @func bbmod_light_punctual_add(_light) diff --git a/BBMOD_GML/scripts/BBMOD_ReflectionProbe/BBMOD_ReflectionProbe.gml b/BBMOD_GML/scripts/BBMOD_ReflectionProbe/BBMOD_ReflectionProbe.gml index 36e549f8..0f256989 100644 --- a/BBMOD_GML/scripts/BBMOD_ReflectionProbe/BBMOD_ReflectionProbe.gml +++ b/BBMOD_GML/scripts/BBMOD_ReflectionProbe/BBMOD_ReflectionProbe.gml @@ -115,6 +115,8 @@ function BBMOD_ReflectionProbe(_position=undefined, _sprite=undefined) construct /// Equals `true` when `_sprite` is not passed to the constructor. **Setting /// this to `true` every frame has severe impact on performance, even for a /// single reflection probe!** + /// @note This is automatically reset to `false` when the reflection probe is + /// captured. NeedsUpdate = (_sprite == undefined); /// @func set_position(_position) diff --git a/BBMOD_GML/scripts/BBMOD_RenderQueue/BBMOD_RenderQueue.gml b/BBMOD_GML/scripts/BBMOD_RenderQueue/BBMOD_RenderQueue.gml index e737fe18..17b9a65d 100644 --- a/BBMOD_GML/scripts/BBMOD_RenderQueue/BBMOD_RenderQueue.gml +++ b/BBMOD_GML/scripts/BBMOD_RenderQueue/BBMOD_RenderQueue.gml @@ -1750,17 +1750,17 @@ function BBMOD_RenderQueue(_name=undefined, _priority=0) constructor matrix_set(matrix_world, _matrix); set_material_index(_mesh.MaterialIndex); } - - var _baseOpacity = _material.BaseOpacity; - if (global.__bbmodMaterialProps != undefined) - { - var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); - if (_baseOpacityProp != undefined) - { - _baseOpacity = _baseOpacityProp; - } - } - + + var _baseOpacity = _material.BaseOpacity; + if (global.__bbmodMaterialProps != undefined) + { + var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); + if (_baseOpacityProp != undefined) + { + _baseOpacity = _baseOpacityProp; + } + } + vertex_submit(_mesh.VertexBuffer, _mesh.PrimitiveType, _baseOpacity); global.__bbmodMaterialProps = _materialPropsOld; @@ -1795,16 +1795,16 @@ function BBMOD_RenderQueue(_name=undefined, _priority=0) constructor set_bones(_boneData); } - var _baseOpacity = _material.BaseOpacity; - if (global.__bbmodMaterialProps != undefined) - { - var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); - if (_baseOpacityProp != undefined) - { - _baseOpacity = _baseOpacityProp; - } - } - + var _baseOpacity = _material.BaseOpacity; + if (global.__bbmodMaterialProps != undefined) + { + var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); + if (_baseOpacityProp != undefined) + { + _baseOpacity = _baseOpacityProp; + } + } + vertex_submit(_mesh.VertexBuffer, _mesh.PrimitiveType, _baseOpacity); global.__bbmodMaterialProps = _materialPropsOld; @@ -1955,17 +1955,17 @@ function BBMOD_RenderQueue(_name=undefined, _priority=0) constructor var _primitiveType = _mesh.PrimitiveType; var _vertexBuffer = _mesh.VertexBuffer; - - var _baseOpacity = _material.BaseOpacity; - if (global.__bbmodMaterialProps != undefined) - { - var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); - if (_baseOpacityProp != undefined) - { - _baseOpacity = _baseOpacityProp; - } + + var _baseOpacity = _material.BaseOpacity; + if (global.__bbmodMaterialProps != undefined) + { + var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); + if (_baseOpacityProp != undefined) + { + _baseOpacity = _baseOpacityProp; + } } - + if (is_array(_batchData[0])) { var _dataIndex = 0; @@ -2463,17 +2463,17 @@ function BBMOD_RenderQueue(_name=undefined, _priority=0) constructor { var _vertexBuffer = _command[i++]; var _prim = _command[i++]; - + var _texture = _command[i++]; - if (global.__bbmodMaterialProps != undefined) - { - var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); - if (_baseOpacityProp != undefined) - { - _texture = _baseOpacityProp; - } - } - + if (global.__bbmodMaterialProps != undefined) + { + var _baseOpacityProp = global.__bbmodMaterialProps.get(BBMOD_U_BASE_OPACITY); + if (_baseOpacityProp != undefined) + { + _texture = _baseOpacityProp; + } + } + vertex_submit(_vertexBuffer, _prim, _texture); } break; diff --git a/BBMOD_GML/scripts/BBMOD_SpotLight/BBMOD_SpotLight.gml b/BBMOD_GML/scripts/BBMOD_SpotLight/BBMOD_SpotLight.gml index ca733af6..6f1c0490 100644 --- a/BBMOD_GML/scripts/BBMOD_SpotLight/BBMOD_SpotLight.gml +++ b/BBMOD_GML/scripts/BBMOD_SpotLight/BBMOD_SpotLight.gml @@ -33,21 +33,13 @@ function BBMOD_SpotLight( /// @var {Real} The inner cone angle in degrees. Default value is 20. AngleOuter = _angleOuter; - - __getZFar = __get_shadowmap_zfar; - + __getViewMatrix = __get_shadowmap_view; __getProjMatrix = __get_shadowmap_projection; __getShadowmapMatrix = __get_shadowmap_matrix; - static __get_shadowmap_zfar = function () - { - gml_pragma("forceinline"); - return Range; - }; - static __get_shadowmap_view = function () { gml_pragma("forceinline"); diff --git a/BBMOD_GML/scripts/BBMOD_Terrain/BBMOD_Terrain.gml b/BBMOD_GML/scripts/BBMOD_Terrain/BBMOD_Terrain.gml index 057c33de..78e5a229 100644 --- a/BBMOD_GML/scripts/BBMOD_Terrain/BBMOD_Terrain.gml +++ b/BBMOD_GML/scripts/BBMOD_Terrain/BBMOD_Terrain.gml @@ -699,8 +699,8 @@ function BBMOD_Terrain(_heightmap=undefined, _subimage=0, _chunkSize=128) constr return self; } - var _shader = Material.get_shader(BBMOD_ERenderPass.Forward) - ?? Material.get_shader(BBMOD_ERenderPass.GBuffer); + var _shader = Material.get_shader(BBMOD_ERenderPass.GBuffer) + ?? Material.get_shader(BBMOD_ERenderPass.Forward); if (_shader == undefined) { return self; @@ -795,7 +795,8 @@ function BBMOD_Terrain(_heightmap=undefined, _subimage=0, _chunkSize=128) constr //gpu_set_colorwriteenable(true, true, true, false); if (_renderPass != BBMOD_ERenderPass.Forward - && _renderPass != BBMOD_ERenderPass.ReflectionCapture) + && _renderPass != BBMOD_ERenderPass.ReflectionCapture + && _renderPass != BBMOD_ERenderPass.GBuffer) { break; } @@ -826,8 +827,8 @@ function BBMOD_Terrain(_heightmap=undefined, _subimage=0, _chunkSize=128) constr else { texture_set_stage(_uTerrainBaseOpacity[i], _baseOpacity); - } - + } + shader_set_uniform_i(_uSplatmapIndex[i], _layerIndices[_call + i] - 1); texture_set_stage(_uTerrainNormalW[i], _layerNormalRoughness ?? (_layer[$ "NormalSmoothness"] ?? _normalWDefault)); shader_set_uniform_f(_uTerrainIsRoughness[i], (_layerNormalRoughness != undefined) ? 1.0 : 0.0); @@ -867,8 +868,8 @@ function BBMOD_Terrain(_heightmap=undefined, _subimage=0, _chunkSize=128) constr /// @return {Struct.BBMOD_Terrain} Returns `self`. static render = function () { - var _shader = Material.get_shader(BBMOD_ERenderPass.Forward) - ?? Material.get_shader(BBMOD_ERenderPass.GBuffer); + var _shader = Material.get_shader(BBMOD_ERenderPass.GBuffer) + ?? Material.get_shader(BBMOD_ERenderPass.Forward); if (_shader == undefined) { return self; @@ -942,7 +943,9 @@ function BBMOD_Terrain(_heightmap=undefined, _subimage=0, _chunkSize=128) constr else { RenderQueue - .CheckRenderPass((1 << BBMOD_ERenderPass.Forward) | (1 << BBMOD_ERenderPass.ReflectionCapture)) + .CheckRenderPass((1 << BBMOD_ERenderPass.Forward) + | (1 << BBMOD_ERenderPass.ReflectionCapture) + | (1 << BBMOD_ERenderPass.GBuffer)) .BeginConditionalBlock() //.SetGpuBlendEnable(true) //.SetGpuColorWriteEnable(true, true, true, false) diff --git a/BBMOD_GML/scripts/BBMOD_TerrainMaterial/BBMOD_TerrainMaterial.gml b/BBMOD_GML/scripts/BBMOD_TerrainMaterial/BBMOD_TerrainMaterial.gml index c1ef0bbb..94d18c28 100644 --- a/BBMOD_GML/scripts/BBMOD_TerrainMaterial/BBMOD_TerrainMaterial.gml +++ b/BBMOD_GML/scripts/BBMOD_TerrainMaterial/BBMOD_TerrainMaterial.gml @@ -15,4 +15,10 @@ function BBMOD_TerrainMaterial(_shader=undefined) : BBMOD_BaseMaterial(_shader) constructor { + static clone = function () + { + var _clone = new BBMOD_TerrainMaterial(); + copy(_clone); + return _clone; + }; } diff --git a/BBMOD_GML/scripts/MatZombie/MatZombie.gml b/BBMOD_GML/scripts/MatZombie/MatZombie.gml index e8c59f1f..39d0664c 100644 --- a/BBMOD_GML/scripts/MatZombie/MatZombie.gml +++ b/BBMOD_GML/scripts/MatZombie/MatZombie.gml @@ -5,13 +5,21 @@ function MatZombie() static _material = undefined; if (_material == undefined) { - _shader = new BBMOD_DefaultShader(ShZombie, BBMOD_VFORMAT_DEFAULT_ANIMATED); + var _deferred = bbmod_deferred_renderer_is_supported(); + _shader = new BBMOD_DefaultShader(_deferred ? ShZombieGBuffer : ShZombie, BBMOD_VFORMAT_DEFAULT_ANIMATED); _shaderDepth = new BBMOD_BaseShader(ShZombieDepth, BBMOD_VFORMAT_DEFAULT_ANIMATED); - _material = BBMOD_MATERIAL_DEFAULT.clone() - .set_shader(BBMOD_ERenderPass.Forward, _shader) - .set_shader(BBMOD_ERenderPass.DepthOnly, _shaderDepth) + _material = BBMOD_MATERIAL_DEFERRED.clone() .set_shader(BBMOD_ERenderPass.Id, BBMOD_SHADER_INSTANCE_ID) // Enable instance selecting .set_shader(BBMOD_ERenderPass.Shadows, _shaderDepth); // Enable casting shadows + if (_deferred) + { + _material.set_shader(BBMOD_ERenderPass.GBuffer, _shader); + } + else + { + _material.set_shader(BBMOD_ERenderPass.Forward, _shader) + .set_shader(BBMOD_ERenderPass.DepthOnly, _shaderDepth); + } _material.Culling = cull_noculling; } return _material; diff --git a/BBMOD_GML/scripts/__bbmod_deferred_material/__bbmod_deferred_material.gml b/BBMOD_GML/scripts/__bbmod_deferred_material/__bbmod_deferred_material.gml new file mode 100644 index 00000000..0fbdab39 --- /dev/null +++ b/BBMOD_GML/scripts/__bbmod_deferred_material/__bbmod_deferred_material.gml @@ -0,0 +1,72 @@ +/// @module DeferredRenderer + +/// @macro {Struct.BBMOD_DefaultShader} A shader for rendering models into the +/// G-buffer. +#macro BBMOD_SHADER_GBUFFER __bbmod_shader_gbuffer() + +/// @macro {Struct.BBMOD_DefaultMaterial} An opaque material that can be used +/// with {@link BBMOD_DeferredRenderer}. +#macro BBMOD_MATERIAL_DEFERRED __bbmod_material_deferred() + +/// @macro {Struct.BBMOD_TerrainShader} A shader for rendering terrain into +/// the G-buffer. Supports 3 terrain layers at most! +#macro BBMOD_SHADER_TERRAIN_GBUFFER __bbmod_shader_terrain_gbuffer() + +/// @macro {Struct.BBMOD_TerrainMaterial} A terrain material that can be used +/// with {@link BBMOD_DeferredRenderer}. +#macro BBMOD_MATERIAL_TERRAIN_DEFERRED __bbmod_material_terrain_deferred() + +function __bbmod_shader_gbuffer() +{ + gml_pragma("forceinline"); + static _shader = new BBMOD_DefaultShader( + BBMOD_ShGBuffer, BBMOD_VFORMAT_DEFAULT) + .add_variant(BBMOD_ShGBufferAnimated, BBMOD_VFORMAT_DEFAULT_ANIMATED) + .add_variant(BBMOD_ShGBufferBatched, BBMOD_VFORMAT_DEFAULT_BATCHED) + .add_variant(BBMOD_ShGBufferColor, BBMOD_VFORMAT_DEFAULT_COLOR) + .add_variant(BBMOD_ShGBufferColorAnimated, BBMOD_VFORMAT_DEFAULT_COLOR_ANIMATED) + .add_variant(BBMOD_ShGBufferColorBatched, BBMOD_VFORMAT_DEFAULT_COLOR_BATCHED); + return _shader; +} + +function __bbmod_material_deferred() +{ + gml_pragma("forceinline"); + static _material = new BBMOD_DefaultMaterial() + .set_shader(BBMOD_ERenderPass.GBuffer, BBMOD_SHADER_GBUFFER); + return _material; +} + +function __bbmod_shader_terrain_gbuffer() +{ + static _shader = undefined; + if (_shader == undefined) + { + _shader = new BBMOD_TerrainShader(BBMOD_ShGBufferTerrain, BBMOD_VFORMAT_DEFAULT); + _shader.LayersPerDrawCall = 3; + _shader.MaxLayers = 3; + } + return _shader; +} + +function __bbmod_material_terrain_deferred() +{ + static _material = undefined; + if (_material == undefined) + { + _material = new BBMOD_TerrainMaterial(); + _material.set_shader(BBMOD_ERenderPass.GBuffer, BBMOD_SHADER_TERRAIN_GBUFFER); + _material.set_shader(BBMOD_ERenderPass.ReflectionCapture, BBMOD_SHADER_TERRAIN); + _material.set_shader(BBMOD_ERenderPass.Shadows, BBMOD_SHADER_DEFAULT_DEPTH); + _material.Repeat = true; + _material.AlphaTest = 0.01; + _material.AlphaBlend = false; + } + return _material; +} + +bbmod_shader_register("BBMOD_SHADER_GBUFFER", BBMOD_SHADER_GBUFFER); +bbmod_shader_register("BBMOD_SHADER_TERRAIN_GBUFFER", BBMOD_SHADER_TERRAIN_GBUFFER); + +bbmod_material_register("BBMOD_MATERIAL_DEFERRED", BBMOD_MATERIAL_TERRAIN); +bbmod_material_register("BBMOD_MATERIAL_TERRAIN_DEFERRED", BBMOD_MATERIAL_TERRAIN_UNLIT); diff --git a/BBMOD_GML/scripts/__bbmod_deferred_material/__bbmod_deferred_material.yy b/BBMOD_GML/scripts/__bbmod_deferred_material/__bbmod_deferred_material.yy new file mode 100644 index 00000000..fe8f30c2 --- /dev/null +++ b/BBMOD_GML/scripts/__bbmod_deferred_material/__bbmod_deferred_material.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "__bbmod_deferred_material", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "DeferredRenderer", + "path": "folders/BBMOD/DeferredRenderer.yy", + }, +} \ No newline at end of file diff --git a/BBMOD_GML/scripts/__bbmod_defines/__bbmod_defines.gml b/BBMOD_GML/scripts/__bbmod_defines/__bbmod_defines.gml index b45417de..53683f53 100644 --- a/BBMOD_GML/scripts/__bbmod_defines/__bbmod_defines.gml +++ b/BBMOD_GML/scripts/__bbmod_defines/__bbmod_defines.gml @@ -9,10 +9,10 @@ #macro BBMOD_RELEASE_MAJOR 3 /// @macro {Real} The minor version number of this BBMOD release. -#macro BBMOD_RELEASE_MINOR 19 +#macro BBMOD_RELEASE_MINOR 20 /// @macro {Real} The patch version number of this BBMOD release. -#macro BBMOD_RELEASE_PATCH 3 +#macro BBMOD_RELEASE_PATCH 0 /// @macro {String} The version of this BBMOD release as a string ("major.minor.patch" format). #macro BBMOD_RELEASE_STRING $"{BBMOD_RELEASE_MAJOR}.{BBMOD_RELEASE_MINOR}.{BBMOD_RELEASE_PATCH}" @@ -52,362 +52,3 @@ /// @see BBMOD_NORMALS_NONE /// @see BBMOD_NORMALS_FLAT #macro BBMOD_NORMALS_SMOOTH 2 - -//////////////////////////////////////////////////////////////////////////////// -// -// Vertex shader uniforms -// - -/// @macro {String} Name of a vertex shader uniform of type `mat4` that holds -/// a matrix using which normal vectors of vertices are transformed. -/// @see bbmod_matrix_build_normalmatrix -#macro BBMOD_U_NORMAL_MATRIX "bbmod_NormalMatrix" - -/// @macro {String} Name of a vertex shader uniform of type `vec2` that holds -/// offset of texture coordinates. -#macro BBMOD_U_TEXTURE_OFFSET "bbmod_TextureOffset" - -/// @macro {String} Name of a vertex shader uniform of type `vec2` that holds -/// scale of texture coordinates. -#macro BBMOD_U_TEXTURE_SCALE "bbmod_TextureScale" - -/// @macro {String} Name of a vertex shader uniform of type -/// `vec4[2 * BBMOD_MAX_BONES]` that holds bone transformation data. -/// @see BBMOD_MAX_BONES -#macro BBMOD_U_BONES "bbmod_Bones" - -/// @macro {String} Name of a vertex shader uniform of type -/// `vec4[BBMOD_MAX_BATCH_VEC4S]` that holds dynamic batching data. -/// @see BBMOD_MAX_BATCH_VEC4S -#macro BBMOD_U_BATCH_DATA "bbmod_BatchData" - -/// @macro {String} Name of a vertex shader uniform of type `float` that holds -/// whether shadowmapping is enabled (1.0) or disabled (0.0). -#macro BBMOD_U_SHADOWMAP_ENABLE_VS "bbmod_ShadowmapEnableVS" - -/// @macro {String} Name of a vertex shader uniform of type `mat4` that holds -/// a matrix that transforms vertices from world-space to shadowmap-space. -#macro BBMOD_U_SHADOWMAP_MATRIX "bbmod_ShadowmapMatrix" - -/// @macro {String} Name of a vertex shader uniform of type `float` that holds -/// how much are vertices offset by their normal before they are transformed into -/// shadowmap-space, using formula `vertex + normal * normalOffset`. -#macro BBMOD_U_SHADOWMAP_NORMAL_OFFSET "bbmod_ShadowmapNormalOffset" - -//////////////////////////////////////////////////////////////////////////////// -// -// Fragment shader uniforms -// - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// an ID of the instance that draws the model, encoded into a color. -/// -/// @example -/// ```gml -/// shader_set_uniform_f( -/// shader_get_uniform(shader_current(), BBMOD_U_INSTANCE_ID), -/// ((id & $000000FF) >> 0) / 255, -/// ((id & $0000FF00) >> 8) / 255, -/// ((id & $00FF0000) >> 16) / 255, -/// ((id & $FF000000) >> 24) / 255); -/// ``` -/// -/// @see bbmod_set_instance_id -#macro BBMOD_U_INSTANCE_ID "bbmod_InstanceID" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the index of the current material within array {@link BBMOD_Model.Materials}. -#macro BBMOD_U_MATERIAL_INDEX "bbmod_MaterialIndex" - -/// @var {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with base color in RGB channels and opacity in the A channel. -#macro BBMOD_U_BASE_OPACITY "gm_BaseTexture" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// a multiplier for the base opacity texture (`gm_BaseTexture`). -#macro BBMOD_U_BASE_OPACITY_MULTIPLIER "bbmod_BaseOpacityMultiplier" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether the material uses roughness workflow (1.0) or not (0.0). -#macro BBMOD_U_IS_ROUGHNESS "bbmod_IsRoughness" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether the material uses metallic workflow (1.0) or not (0.0). -#macro BBMOD_U_IS_METALLIC "bbmod_IsMetallic" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds normal smoothness/roughness texture. -#macro BBMOD_U_NORMAL_W "bbmod_NormalW" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with either metalness in the R channel and ambient occlusion -/// in the G channel (for materials using metallic workflow), or specular color -/// in RGB (for materials using specular color workflow). -#macro BBMOD_U_MATERIAL "bbmod_Material" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with subsurface color in RGB and subsurface effect intensity -/// (or model thickness) in the A channel. -#macro BBMOD_U_SUBSURFACE "bbmod_Subsurface" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with RGBM encoded emissive color. -#macro BBMOD_U_EMISSIVE "bbmod_Emissive" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with a baked lightmap applied to the model. -/// @see bbmod_lightmap_set -/// @see bbmod_lightmap_get -#macro BBMOD_U_LIGHTMAP "bbmod_Lightmap" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// top left and bottom right coordinates of the base opacity texture on its -/// texture page. -#macro BBMOD_U_BASE_OPACITY_UV "bbmod_BaseOpacityUV" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// top left and bottom right coordinates of the normal texture on its texture -/// page. -#macro BBMOD_U_NORMAL_W_UV "bbmod_NormalWUV" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// top left and bottom right coordinates of the material texture on its texture -/// page. -#macro BBMOD_U_MATERIAL_UV "bbmod_MaterialUV" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the alpha test threshold value. Fragments with alpha less than this value are -/// discarded. -#macro BBMOD_U_ALPHA_TEST "bbmod_AlphaTest" - -/// @macro {String} Name of a fragment shader uniform of type `vec3` that holds -/// the world-space camera position. -/// @see bbmod_camera_set_position -/// @see bbmod_camera_get_position -#macro BBMOD_U_CAM_POS "bbmod_CamPos" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the distance to the far clipping plane. -/// @see bbmod_camera_set_zfar -/// @see bbmod_camera_get_zfar -#macro BBMOD_U_ZFAR "bbmod_ZFar" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the camera exposure value. -/// @see bbmod_camera_set_exposure -/// @see bbmod_camera_get_exposure -#macro BBMOD_U_EXPOSURE "bbmod_Exposure" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds the G-buffer texture. This can also be just the depth texture in a -/// forward rendering pipeline. -#macro BBMOD_U_GBUFFER "bbmod_GBuffer" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// a distance over which particles smoothly disappear when intersecting with -/// geometry in the depth buffer. -#macro BBMOD_U_SOFT_DISTANCE "bbmod_SoftDistance" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// the fog color. -/// @see bbmod_fog_set_color -/// @see bbmod_fog_get_color -#macro BBMOD_U_FOG_COLOR "bbmod_FogColor" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the maximum fog intensity. -/// @see bbmod_fog_set_intensity -/// @see bbmod_fog_get_intensity -#macro BBMOD_U_FOG_INTENSITY "bbmod_FogIntensity" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the distance from the camera at which the fog starts. -/// @see bbmod_fog_set_start -/// @see bbmod_fog_get_start -#macro BBMOD_U_FOG_START "bbmod_FogStart" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// `1.0 / (fogEnd - fogStart)`, where `fogEnd` is the distance from the camera -/// where fog reaches its maximum intensity and `fogStart` is the distance from -/// camera where the fog begins. -/// @see bbmod_fog_set_end -/// @see bbmod_fog_get_end -#macro BBMOD_U_FOG_RCP_RANGE "bbmod_FogRcpRange" - -/// @macro {String} Name of a fragment shader uniform of type `vec3` that holds -/// the ambient light's up vector. -/// @see bbmod_light_ambient_set_dir -/// @see bbmod_light_ambient_get_dir -#macro BBMOD_U_LIGHT_AMBIENT_DIR_UP "bbmod_LightAmbientDirUp" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// the ambient light color on the upper hemisphere. -/// @see bbmod_light_ambient_set_up -/// @see bbmod_light_ambient_get_up -#macro BBMOD_U_LIGHT_AMBIENT_UP "bbmod_LightAmbientUp" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// the ambient light color on the lower hemisphere. -/// @see bbmod_light_ambient_set_down -/// @see bbmod_light_ambient_get_down -#macro BBMOD_U_LIGHT_AMBIENT_DOWN "bbmod_LightAmbientDown" - -/// @macro {String} Name of a fragment shader uniform of type `vec3` that holds -/// the directional light's direction. -/// @see bbmod_light_directional_set -/// @see bbmod_light_directional_get -#macro BBMOD_U_LIGHT_DIRECTIONAL_DIR "bbmod_LightDirectionalDir" - -/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds -/// the directional light's color in RGB and intensity in the A channel. -/// @see bbmod_light_directional_set -/// @see bbmod_light_directional_get -#macro BBMOD_U_LIGHT_DIRECTIONAL_COLOR "bbmod_LightDirectionalColor" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds the screen-space ambient occlusion texture. -#macro BBMOD_U_SSAO "bbmod_SSAO" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether image based lighting is enabled (1.0) or disabled (0.0). -/// @see bbmod_ibl_set -/// @see bbmod_ibl_get -#macro BBMOD_U_IBL_ENABLE "bbmod_IBLEnable" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds the image based lighting texture. -/// @see bbmod_ibl_set -/// @see bbmod_ibl_get -#macro BBMOD_U_IBL "bbmod_IBL" - -/// @macro {String} Name of a fragment shader uniform of type `vec2` that holds -/// the texel size of image based lighting texture. -/// @see bbmod_ibl_set -/// @see bbmod_ibl_get -#macro BBMOD_U_IBL_TEXEL "bbmod_IBLTexel" - -/// @macro {String} Name of a fragment shader uniform of type -/// `vec4[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]` that holds vectors `(x, y, z, range)` -/// and `(r, g, b, intensity)` for each punctual light. -/// @see BBMOD_MAX_PUNCTUAL_LIGHTS -/// @see bbmod_light_punctual_add -#macro BBMOD_U_LIGHT_PUNCTUAL_DATA_A "bbmod_LightPunctualDataA" - -/// @macro {String} Name of a fragment shader uniform of type -/// `vec3[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]` that holds vectors -/// `(isSpotLight, dcosInner, dcosOuter)` and `(dirX, dirY, dirZ)` for each -/// punctual light. -/// @see BBMOD_MAX_PUNCTUAL_LIGHTS -/// @see bbmod_light_punctual_add -#macro BBMOD_U_LIGHT_PUNCTUAL_DATA_B "bbmod_LightPunctualDataB" - -/// @macro {String} Common part of uniform names {@link BBMOD_U_TERRAIN_BASE_OPACITY_0}, -/// {@link BBMOD_U_TERRAIN_BASE_OPACITY_1} and {@link BBMOD_U_TERRAIN_BASE_OPACITY_2}, -/// which only append a number to it. -#macro BBMOD_U_TERRAIN_BASE_OPACITY "bbmod_TerrainBaseOpacity" - -/// @macro {String} Common part of uniform names {@link BBMOD_U_TERRAIN_NORMAL_W_0}, -/// {@link BBMOD_U_TERRAIN_NORMAL_W_1} and {@link BBMOD_U_TERRAIN_NORMAL_W_2}, -/// which only append a number to it. -#macro BBMOD_U_TERRAIN_NORMAL_W "bbmod_TerrainNormalW" - -/// @macro {String} Common part of uniform names {@link BBMOD_U_TERRAIN_IS_ROUGHNESS_0}, -/// {@link BBMOD_U_TERRAIN_IS_ROUGHNESS_1} and {@link BBMOD_U_TERRAIN_IS_ROUGHNESS_2}, -/// which only append a number to it. -#macro BBMOD_U_TERRAIN_IS_ROUGHNESS "bbmod_TerrainIsRoughness" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with base color in RGB channels and opacity in the A channel -/// for the first terrain layer rendered in a single draw call. -#macro BBMOD_U_TERRAIN_BASE_OPACITY_0 "gm_BaseTexture" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds normal smoothness/roughness texture for the first terrain layer rendered -/// in a single draw call. -#macro BBMOD_U_TERRAIN_NORMAL_W_0 (BBMOD_U_TERRAIN_NORMAL_W + "0") - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether the first terrain material layer uses roughness workflow (1.0) or not (0.0). -#macro BBMOD_U_TERRAIN_IS_ROUGHNESS_0 (BBMOD_U_TERRAIN_IS_ROUGHNESS + "0") - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with base color in RGB channels and opacity in the A channel -/// for the second terrain layer rendered in a single draw call. -#macro BBMOD_U_TERRAIN_BASE_OPACITY_1 (BBMOD_U_TERRAIN_BASE_OPACITY + "1") - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds normal smoothness/roughness texture for the second terrain layer rendered -/// in a single draw call. -#macro BBMOD_U_TERRAIN_NORMAL_W_1 (BBMOD_U_TERRAIN_NORMAL_W + "1") - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether the second terrain material layer uses roughness workflow (1.0) or not (0.0). -#macro BBMOD_U_TERRAIN_IS_ROUGHNESS_1 (BBMOD_U_TERRAIN_IS_ROUGHNESS + "1") - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds a texture with base color in RGB channels and opacity in the A channel -/// for the third terrain layer rendered in a single draw call. -#macro BBMOD_U_TERRAIN_BASE_OPACITY_2 (BBMOD_U_TERRAIN_BASE_OPACITY + "2") - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds normal smoothness/roughness texture for the third terrain layer rendered -/// in a single draw call. -#macro BBMOD_U_TERRAIN_NORMAL_W_2 (BBMOD_U_TERRAIN_NORMAL_W + "2") - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether the third terrain material layer uses roughness workflow (1.0) or not (0.0). -#macro BBMOD_U_TERRAIN_IS_ROUGHNESS_2 (BBMOD_U_TERRAIN_IS_ROUGHNESS + "2") - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds the splatmap texture. -#macro BBMOD_U_SPLATMAP "bbmod_Splatmap" - -/// @macro {String} Common part of uniform names {@link BBMOD_U_SPLATMAP_INDEX_0}, -/// {@link BBMOD_U_SPLATMAP_INDEX_1} and {@link BBMOD_U_SPLATMAP_INDEX_2}, -/// which only append a number to it. -#macro BBMOD_U_SPLATMAP_INDEX "bbmod_SplatmapIndex" - -/// @macro {String} Name of a fragment shader uniform of type `int` that holds -/// the index of a channel to read from the splatmap for the first terrain layer -/// rendered in a draw call. -#macro BBMOD_U_SPLATMAP_INDEX_0 (BBMOD_U_SPLATMAP_INDEX + "0") - -/// @macro {String} Name of a fragment shader uniform of type `int` that holds -/// the index of a channel to read from the splatmap for the second terrain layer -/// rendered in a draw call. -#macro BBMOD_U_SPLATMAP_INDEX_1 (BBMOD_U_SPLATMAP_INDEX + "1") - -/// @macro {String} Name of a fragment shader uniform of type `int` that holds -/// the index of a channel to read from the splatmap for the third terrain layer -/// rendered in a draw call. -#macro BBMOD_U_SPLATMAP_INDEX_2 (BBMOD_U_SPLATMAP_INDEX + "2") - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds the colormap texture. -#macro BBMOD_U_COLORMAP "bbmod_Colormap" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// whether shadowmapping is enabled (1.0) or disabled (0.0). -#macro BBMOD_U_SHADOWMAP_ENABLE_PS "bbmod_ShadowmapEnablePS" - -/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that -/// holds the shadowmap texture. -#macro BBMOD_U_SHADOWMAP "bbmod_Shadowmap" - -/// @macro {String} Name of a fragment shader uniform of type `vec2` that holds -/// the texel size of a shadowmap texture. -#macro BBMOD_U_SHADOWMAP_TEXEL "bbmod_ShadowmapTexel" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the area that the shadowmap captures. -#macro BBMOD_U_SHADOWMAP_AREA "bbmod_ShadowmapArea" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the distance over which models smoothly transition into shadow. Useful for -/// example for volumetric look of particles. -#macro BBMOD_U_SHADOWMAP_BIAS "bbmod_ShadowmapBias" - -/// @macro {String} Name of a fragment shader uniform of type `float` that holds -/// the index of a punctual light that casts shadows or -1.0, if it's the -/// directional light. -#macro BBMOD_U_SHADOW_CASTER_INDEX "bbmod_ShadowCasterIndex" diff --git a/BBMOD_GML/scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.gml b/BBMOD_GML/scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.gml new file mode 100644 index 00000000..2008338c --- /dev/null +++ b/BBMOD_GML/scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.gml @@ -0,0 +1,16 @@ +/// @func __bbmod_matrix_proj_get_tanaspect(_matProj) +/// +/// @desc +/// +/// @param {Array} _matProj +/// +/// @return {Array} +/// +/// @private +function __bbmod_matrix_proj_get_tanaspect(_matProj) +{ + gml_pragma("forceinline"); + return (_matProj[11] == 0.0) + ? [1.0, -1.0] // Ortho + : [1.0 / _matProj[0], -1.0 / _matProj[5]]; // Perspective +} diff --git a/BBMOD_GML/scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.yy b/BBMOD_GML/scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.yy new file mode 100644 index 00000000..547d9944 --- /dev/null +++ b/BBMOD_GML/scripts/__bbmod_matrix_proj_get_tanaspect/__bbmod_matrix_proj_get_tanaspect.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "__bbmod_matrix_proj_get_tanaspect", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "Utils", + "path": "folders/BBMOD/Core/Utils.yy", + }, +} \ No newline at end of file diff --git a/BBMOD_GML/scripts/__bbmod_render_pass/__bbmod_render_pass.gml b/BBMOD_GML/scripts/__bbmod_render_pass/__bbmod_render_pass.gml index 8e70f9ed..f521b0c6 100644 --- a/BBMOD_GML/scripts/__bbmod_render_pass/__bbmod_render_pass.gml +++ b/BBMOD_GML/scripts/__bbmod_render_pass/__bbmod_render_pass.gml @@ -17,10 +17,11 @@ enum BBMOD_ERenderPass DepthOnly = 2, /// @member Render pass where opaque objects are rendered into a G-Buffer. GBuffer, - /// @member Render pass where opaque objects are rendered into the frame - /// buffer. + /// @member Render pass for background objects (e.g. skydome). + Background, + /// @member Render pass for opaque objects. Forward, - /// @member Render pass where alpha-blended objects are rendered. + /// @member Render pass for alpha-blended objects. Alpha, /// @member Render pass where instance IDs are rendered into an off-screen /// buffer. diff --git a/BBMOD_GML/scripts/__bbmod_shader_set/__bbmod_shader_set.gml b/BBMOD_GML/scripts/__bbmod_shader_set/__bbmod_shader_set.gml new file mode 100644 index 00000000..8397a966 --- /dev/null +++ b/BBMOD_GML/scripts/__bbmod_shader_set/__bbmod_shader_set.gml @@ -0,0 +1,1029 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Vertex shader uniforms +// + +/// @macro {String} Name of a vertex shader uniform of type `mat4` that holds +/// a matrix using which normal vectors of vertices are transformed. +/// @see bbmod_matrix_build_normalmatrix +#macro BBMOD_U_NORMAL_MATRIX "bbmod_NormalMatrix" + +/// @func bbmod_shader_set_normal_matrix(_shader, _matrix) +/// +/// @desc Sets the {@link BBMOD_U_NORMAL_MATRIX} uniform to the given matrix. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Array} _matrix The new normal matrix. +/// +/// @see bbmod_matrix_build_normalmatrix +function bbmod_shader_set_normal_matrix(_shader, _matrix) +{ + gml_pragma("forceinline"); + shader_set_uniform_matrix_array( + shader_get_uniform(_shader, BBMOD_U_NORMAL_MATRIX), + _matrix); +} + +/// @macro {String} Name of a vertex shader uniform of type `vec2` that holds +/// offset of texture coordinates. +#macro BBMOD_U_TEXTURE_OFFSET "bbmod_TextureOffset" + +/// @func bbmod_shader_set_texture_offset(_shader, _offset) +/// +/// @desc Sets the {@link BBMOD_U_TEXTURE_OFFSET} uniform to the given offset. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Struct.BBMOD_Vec2} _offset The texture offset. +function bbmod_shader_set_texture_offset(_shader, _offset) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_TEXTURE_OFFSET), + _offset.X, _offset.Y); +} + +/// @macro {String} Name of a vertex shader uniform of type `vec2` that holds +/// scale of texture coordinates. +#macro BBMOD_U_TEXTURE_SCALE "bbmod_TextureScale" + +/// @func bbmod_shader_set_texture_scale(_shader, _scale) +/// +/// @desc Sets the {@link BBMOD_U_TEXTURE_SCALE} uniform to the given scale. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Struct.BBMOD_Vec2} _scale The texture scale. +function bbmod_shader_set_texture_scale(_shader, _scale) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_TEXTURE_SCALE), + _scale.X, _scale.Y); +} + + +/// @macro {String} Name of a vertex shader uniform of type +/// `vec4[2 * BBMOD_MAX_BONES]` that holds bone transformation data. +/// @see BBMOD_MAX_BONES +#macro BBMOD_U_BONES "bbmod_Bones" + +/// @func bbmod_shader_set_bones(_shader, _bones) +/// +/// @desc Sets the {@link BBMOD_U_BONES} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Array} _bones The array of bone transforms. +/// +/// @see BBMOD_AnimationPlayer.get_transform +function bbmod_shader_set_bones(_shader, _bones) +{ + gml_pragma("forceinline"); + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_BONES), + _bones); +} + +/// @macro {String} Name of a vertex shader uniform of type +/// `vec4[BBMOD_MAX_BATCH_VEC4S]` that holds dynamic batching data. +/// @see BBMOD_MAX_BATCH_VEC4S +#macro BBMOD_U_BATCH_DATA "bbmod_BatchData" + +/// @func bbmod_shader_set_batch_data(_shader, _data) +/// +/// @desc Sets the {@link BBMOD_U_BATCH_DATA} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Array} _data The dynamic batch data. +function bbmod_shader_set_batch_data(_shader, _data) +{ + gml_pragma("forceinline"); + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_BATCH_DATA), + _data); +} + +/// @macro {String} Name of a vertex shader uniform of type `float` that holds +/// whether shadowmapping is enabled (1.0) or disabled (0.0). +#macro BBMOD_U_SHADOWMAP_ENABLE_VS "bbmod_ShadowmapEnableVS" + +/// @macro {String} Name of a vertex shader uniform of type `mat4` that holds +/// a matrix that transforms vertices from world-space to shadowmap-space. +#macro BBMOD_U_SHADOWMAP_MATRIX "bbmod_ShadowmapMatrix" + +/// @macro {String} Name of a vertex shader uniform of type `float` that holds +/// how much are vertices offset by their normal before they are transformed into +/// shadowmap-space, using formula `vertex + normal * normalOffset`. +/// @obsolete Please use {@link BBMOD_U_SHADOWMAP_NORMAL_OFFSET_VS} instead. +#macro BBMOD_U_SHADOWMAP_NORMAL_OFFSET "bbmod_ShadowmapNormalOffset" + +/// @macro {String} Name of a vertex shader uniform of type `float` that holds +/// how much are vertices offset by their normal before they are transformed into +/// shadowmap-space, using formula `vertex + normal * normalOffset`. +#macro BBMOD_U_SHADOWMAP_NORMAL_OFFSET_VS "bbmod_ShadowmapNormalOffsetVS" + +//////////////////////////////////////////////////////////////////////////////// +// +// Fragment shader uniforms +// + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// an ID of the instance that draws the model, encoded into a color. +/// +/// @example +/// ```gml +/// shader_set_uniform_f( +/// shader_get_uniform(_shader, BBMOD_U_INSTANCE_ID), +/// ((id & $000000FF) >> 0) / 255, +/// ((id & $0000FF00) >> 8) / 255, +/// ((id & $00FF0000) >> 16) / 255, +/// ((id & $FF000000) >> 24) / 255); +/// ``` +/// +/// @see bbmod_set_instance_id +#macro BBMOD_U_INSTANCE_ID "bbmod_InstanceID" + +/// @func bbmod_shader_set_instance_id(_shader[, _id]) +/// +/// @desc Sets the {@link BBMOD_U_INSTANCE_ID} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Id.Instance} [_id] The instance ID. If `undefined`, +/// then the value set by {@link bbmod_set_instance_id} is used. +function bbmod_shader_set_instance_id(_shader, _id=undefined) +{ + gml_pragma("forceinline"); + _id ??= global.__bbmodInstanceID; + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_INSTANCE_ID), + ((_id & $000000FF) >> 0) / 255, + ((_id & $0000FF00) >> 8) / 255, + ((_id & $00FF0000) >> 16) / 255, + ((_id & $FF000000) >> 24) / 255); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the index of the current material within array {@link BBMOD_Model.Materials}. +#macro BBMOD_U_MATERIAL_INDEX "bbmod_MaterialIndex" + +/// @func bbmod_shader_set_material_index(_shader, _index) +/// +/// @desc Sets the {@link BBMOD_U_MATERIAL_INDEX} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Real} [_index] The index of the current material. +function bbmod_shader_set_material_index(_shader, _index) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_MATERIAL_INDEX), + _index); +} + +/// @var {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with base color in RGB channels and opacity in the A channel. +#macro BBMOD_U_BASE_OPACITY "gm_BaseTexture" + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// a multiplier for the base opacity texture (`gm_BaseTexture`). +#macro BBMOD_U_BASE_OPACITY_MULTIPLIER "bbmod_BaseOpacityMultiplier" + +/// @func bbmod_shader_set_base_opacity_multiplier(_shader, _color) +/// +/// @desc Sets the {@link BBMOD_U_BASE_OPACITY_MULTIPLIER} uniform to the given +/// color. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Struct.BBMOD_Color} _color The new base opacity multiplier. +function bbmod_shader_set_base_opacity_multiplier(_shader, _color) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_BASE_OPACITY_MULTIPLIER), + _color.Red / 255.0, + _color.Green / 255.0, + _color.Blue / 255.0, + _color.Alpha); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether the material uses roughness workflow (1.0) or not (0.0). +#macro BBMOD_U_IS_ROUGHNESS "bbmod_IsRoughness" + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds normal smoothness/roughness texture. +#macro BBMOD_U_NORMAL_W "bbmod_NormalW" + +/// @func bbmod_shader_set_normal_smoothness(_shader, _texture) +/// +/// @desc Sets uniforms {@link BBMOD_U_NORMAL_W} and {@link BBMOD_U_IS_ROUGHNESS}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Pointer.Texture} _texture The new texture with normal vector i +/// the RGB channels and smoothness in the A channel. +function bbmod_shader_set_normal_smoothness(_shader, _texture) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IS_ROUGHNESS), + 0.0); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_NORMAL_W), + _texture); +} + +/// @func bbmod_shader_set_normal_roughness(_shader, _texture) +/// +/// @desc Sets uniforms {@link BBMOD_U_NORMAL_W} and {@link BBMOD_U_IS_ROUGHNESS}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Pointer.Texture} _texture The new texture with normal vector in +/// the RGB channels and roughness in the A channel. +function bbmod_shader_set_normal_roughness(_shader, _texture) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IS_ROUGHNESS), + 1.0); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_NORMAL_W), + _texture); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether the material uses metallic workflow (1.0) or not (0.0). +#macro BBMOD_U_IS_METALLIC "bbmod_IsMetallic" + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with either metalness in the R channel and ambient occlusion +/// in the G channel (for materials using metallic workflow), or specular color +/// in RGB (for materials using specular color workflow). +#macro BBMOD_U_MATERIAL "bbmod_Material" + +/// @func bbmod_shader_set_specular_color(_shader, _texture) +/// +/// @desc Sets uniforms {@link BBMOD_U_MATERIAL} and {@link BBMOD_U_IS_METALLIC}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Pointer.Texture} _texture The new texture with specular color in +/// the RGB channels. +function bbmod_shader_set_specular_color(_shader, _texture) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IS_METALLIC), + 0.0); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_MATERIAL), + _texture); +} + +/// @func bbmod_shader_set_metallic_ao(_shader, _texture) +/// +/// @desc Sets uniforms {@link BBMOD_U_MATERIAL} and {@link BBMOD_U_IS_METALLIC}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Pointer.Texture} _texture The new texture with metalness in the +/// R channel and ambient occlusion in the G channel. +function bbmod_shader_set_metallic_ao(_shader, _texture) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IS_METALLIC), + 1.0); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_MATERIAL), + _texture); +} + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with subsurface color in RGB and subsurface effect intensity +/// (or model thickness) in the A channel. +#macro BBMOD_U_SUBSURFACE "bbmod_Subsurface" + +/// @func bbmod_shader_set_subsurface(_shader, _texture) +/// +/// @desc Sets the {@link BBMOD_U_SUBSURFACE} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Pointer.Texture} _texture The new texture with subsurface color +/// in the RGB channels and its intensity in the A channel. +function bbmod_shader_set_subsurface(_shader, _texture) +{ + gml_pragma("forceinline"); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_SUBSURFACE), + _texture); +} + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with RGBM encoded emissive color. +#macro BBMOD_U_EMISSIVE "bbmod_Emissive" + +/// @func bbmod_shader_set_emissive(_shader, _texture) +/// +/// @desc Sets the {@link BBMOD_U_EMISSIVE} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Pointer.Texture} _texture The new texture with RGBM encoded +/// emissive color. +function bbmod_shader_set_emissive(_shader, _texture) +{ + gml_pragma("forceinline"); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_EMISSIVE), + _texture); +} + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with a baked lightmap applied to the model. +/// @see bbmod_lightmap_set +/// @see bbmod_lightmap_get +#macro BBMOD_U_LIGHTMAP "bbmod_Lightmap" + +/// @func bbmod_shader_set_lightmap(_shader[, _texture]) +/// +/// @desc Sets the {@link BBMOD_U_LIGHTMAP} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Pointer.Texture} [_texture] The new RGBM encoded lightmap +/// texture. If not specified, defaults to the one configured using +/// {@link bbmod_lightmap_set}. +function bbmod_shader_set_lightmap(_shader, _texture=global.__bbmodLightmap) +{ + gml_pragma("forceinline"); + var _uLightmap = shader_get_sampler_index(_shader, BBMOD_U_LIGHTMAP); + texture_set_stage(_uLightmap, _texture); + gpu_set_tex_mip_enable_ext(_uLightmap, mip_off); + gpu_set_tex_filter_ext(_uLightmap, true); +} + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// top left and bottom right coordinates of the base opacity texture on its +/// texture page. +#macro BBMOD_U_BASE_OPACITY_UV "bbmod_BaseOpacityUV" + +/// @func bbmod_shader_set_base_opacity_uv(_shader, _uv) +/// +/// @desc Sets the {@link BBMOD_U_BASE_OPACITY_UV} uniform to given values. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Array} _uv The new base opacity texture UVs as `[left, top, right bottom]` +/// (same as function `texture_get_uvs` returns). +function bbmod_shader_set_base_opacity_uv(_shader, _uv) +{ + gml_pragma("forceinline"); + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_BASE_OPACITY_UV), + _uv); +} + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// top left and bottom right coordinates of the normal texture on its texture +/// page. +#macro BBMOD_U_NORMAL_W_UV "bbmod_NormalWUV" + +function bbmod_shader_set_normal_w_uv(_shader, _uv) +{ + gml_pragma("forceinline"); + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_NORMAL_W_UV), + _uv); +} + + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// top left and bottom right coordinates of the material texture on its texture +/// page. +#macro BBMOD_U_MATERIAL_UV "bbmod_MaterialUV" + +function bbmod_shader_set_material_uv(_shader, _uv) +{ + gml_pragma("forceinline"); + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_MATERIAL_UV), + _uv); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the alpha test threshold value. Fragments with alpha less than this value are +/// discarded. +#macro BBMOD_U_ALPHA_TEST "bbmod_AlphaTest" + +/// @func bbmod_shader_set_alpha_test(_shader, _value) +/// +/// @desc Sets the {@link BBMOD_U_ALPHA_TEST} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Real} _value The alpha test value. +function bbmod_shader_set_alpha_test(_shader, _value) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_ALPHA_TEST), + _value); +} + + +/// @macro {String} Name of a fragment shader uniform of type `vec3` that holds +/// the world-space camera position. +/// @see bbmod_camera_set_position +/// @see bbmod_camera_get_position +#macro BBMOD_U_CAM_POS "bbmod_CamPos" + +/// @func bbmod_shader_set_cam_pos(_shader[, _pos]) +/// +/// @desc Sets a fragment shader uniform {@link BBMOD_U_CAM_POS} to the given position. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Struct.BBMOD_Vec3} [_pos] The camera position. If `undefined`, +/// then the value set by {@link bbmod_camera_set_position} is used. +function bbmod_shader_set_cam_pos(_shader, _pos=undefined) +{ + gml_pragma("forceinline"); + _pos ??= global.__bbmodCameraPosition; + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_CAM_POS), + _pos.X, _pos.Y, _pos.Z); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the distance to the far clipping plane. +/// @see bbmod_camera_set_zfar +/// @see bbmod_camera_get_zfar +#macro BBMOD_U_ZFAR "bbmod_ZFar" + +/// @func bbmod_shader_set_zfar(_shader[, _zfar]) +/// +/// @desc Sets the {@link BBMOD_U_ZFAR} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Real} [_zfar] The new Z far value. Defaults to the value set using +/// {@link bbmod_camera_set_zfar} if `undefined`. +function bbmod_shader_set_zfar(_shader, _zfar=undefined) +{ + gml_pragma("forceinline"); + _zfar ??= global.__bbmodZFar; + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_ZFAR), + _zfar); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the camera exposure value. +/// @see bbmod_camera_set_exposure +/// @see bbmod_camera_get_exposure +#macro BBMOD_U_EXPOSURE "bbmod_Exposure" + +/// @func bbmod_shader_set_exposure(_shader[, _value]) +/// +/// @desc Sets the {@link BBMOD_U_EXPOSURE} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Real} [_value] The camera exposure. If `undefined`, +/// then the value set by {@link bbmod_camera_set_exposure} is used. +function bbmod_shader_set_exposure(_shader, _value=undefined) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_EXPOSURE), + _value ?? global.__bbmodCameraExposure); +} + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds the G-buffer texture. This can also be just the depth texture in a +/// forward rendering pipeline. +#macro BBMOD_U_GBUFFER "bbmod_GBuffer" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// a distance over which particles smoothly disappear when intersecting with +/// geometry in the depth buffer. +#macro BBMOD_U_SOFT_DISTANCE "bbmod_SoftDistance" + +/// @func bbmod_shader_set_soft_distance(_shader, _value) +/// +/// @desc Sets the {@link BBMOD_U_SOFT_DISTANCE} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Real} _value The new soft distance value. +function bbmod_shader_set_soft_distance(_shader, _value) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_SOFT_DISTANCE), + _value); +} + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// the fog color. +/// @see bbmod_fog_set_color +/// @see bbmod_fog_get_color +#macro BBMOD_U_FOG_COLOR "bbmod_FogColor" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the maximum fog intensity. +/// @see bbmod_fog_set_intensity +/// @see bbmod_fog_get_intensity +#macro BBMOD_U_FOG_INTENSITY "bbmod_FogIntensity" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the distance from the camera at which the fog starts. +/// @see bbmod_fog_set_start +/// @see bbmod_fog_get_start +#macro BBMOD_U_FOG_START "bbmod_FogStart" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// `1.0 / (fogEnd - fogStart)`, where `fogEnd` is the distance from the camera +/// where fog reaches its maximum intensity and `fogStart` is the distance from +/// camera where the fog begins. +/// @see bbmod_fog_set_end +/// @see bbmod_fog_get_end +#macro BBMOD_U_FOG_RCP_RANGE "bbmod_FogRcpRange" + +/// @func bbmod_shader_set_fog(_shader[, _color[, _intensity[, _start[, _end]]]]) +/// +/// @desc Sets uniforms {@link BBMOD_U_FOG_COLOR}, {@link BBMOD_U_FOG_INTENSITY}, +/// {@link BBMOD_U_FOG_START} and {@link BBMOD_U_FOG_RCP_RANGE}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Struct.BBMOD_Color} [_color] The color of the fog. If `undefined`, +/// then the value set by {@link bbmod_fog_set_color} is used. +/// @param {Real} [_intensity] The fog intensity. If `undefined`, then the +/// value set by {@link bbmod_fog_set_intensity} is used. +/// @param {Real} [_start] The distance at which the fog starts. If +/// `undefined`, then the value set by {@link bbmod_fog_set_start} is used. +/// @param {Real} [_end] The distance at which the fog has maximum intensity. +/// If `undefined`, then the value set by {@link bbmod_fog_set_end} is used. +function bbmod_shader_set_fog(_shader, _color=undefined, _intensity=undefined, _start=undefined, _end=undefined) +{ + gml_pragma("forceinline"); + _color ??= global.__bbmodFogColor; + _intensity ??= global.__bbmodFogIntensity; + _start ??= global.__bbmodFogStart; + _end ??= global.__bbmodFogEnd; + var _rcpFogRange = 1.0 / (_end - _start); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_FOG_COLOR), + _color.Red / 255.0, + _color.Green / 255.0, + _color.Blue / 255.0, + _color.Alpha); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_FOG_INTENSITY), + _intensity); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_FOG_START), + _start); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_FOG_RCP_RANGE), + _rcpFogRange); +} + +/// @macro {String} Name of a fragment shader uniform of type `vec3` that holds +/// the ambient light's up vector. +/// @see bbmod_light_ambient_set_dir +/// @see bbmod_light_ambient_get_dir +#macro BBMOD_U_LIGHT_AMBIENT_DIR_UP "bbmod_LightAmbientDirUp" + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// the ambient light color on the upper hemisphere. +/// @see bbmod_light_ambient_set_up +/// @see bbmod_light_ambient_get_up +#macro BBMOD_U_LIGHT_AMBIENT_UP "bbmod_LightAmbientUp" + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// the ambient light color on the lower hemisphere. +/// @see bbmod_light_ambient_set_down +/// @see bbmod_light_ambient_get_down +#macro BBMOD_U_LIGHT_AMBIENT_DOWN "bbmod_LightAmbientDown" + +/// @func bbmod_shader_set_ambient_light(_shader[, _up[, _down[, _dir[, _isLightmapped]]]]) +/// +/// @desc Sets the {@link BBMOD_U_LIGHT_AMBIENT_UP}, {@link BBMOD_U_LIGHT_AMBIENT_DOWN} +/// and {@link BBMOD_U_LIGHT_AMBIENT_DIR_UP} uniforms. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Struct.BBMOD_Color} [_up] Ambient light color on the upper +/// hemisphere. If `undefined`, then the value set by +/// {@link bbmod_light_ambient_set_up} is used. +/// @param {Struct.BBMOD_Color} [_down] Ambient light color on the lower +/// hemisphere. If `undefined`, then the value set by +/// {@link bbmod_light_ambient_set_down} is used. +/// @param {Struct.BBMOD_Vec3} [_dir] Direction to the ambient light's upper +/// hemisphere. If `undefined`, then the value set by +/// {@link bbmod_light_ambient_set_dir} is used. +/// @param {Bool} [_isLightmapped] Use `true` in case the shader renders +/// lightmapped models. Defaults to `false.` +function bbmod_shader_set_ambient_light(_shader, _up=undefined, _down=undefined, _dir=undefined, _isLightmapped=false) +{ + gml_pragma("forceinline"); + if (!_isLightmapped || global.__bbmodAmbientAffectLightmap) + { + _up ??= global.__bbmodAmbientLightUp; + _down ??= global.__bbmodAmbientLightDown; + _dir ??= global.__bbmodAmbientLightDirUp; + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_LIGHT_AMBIENT_UP), + _up.Red / 255.0, + _up.Green / 255.0, + _up.Blue / 255.0, + _up.Alpha); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_LIGHT_AMBIENT_DOWN), + _down.Red / 255.0, + _down.Green / 255.0, + _down.Blue / 255.0, + _down.Alpha); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_LIGHT_AMBIENT_DIR_UP), + _dir.X, + _dir.Y, + _dir.Z); + } + else + { + shader_set_uniform_f(shader_get_uniform(_shader, BBMOD_U_LIGHT_AMBIENT_UP), 0.0, 0.0, 0.0, 0.0); + shader_set_uniform_f(shader_get_uniform(_shader, BBMOD_U_LIGHT_AMBIENT_DOWN), 0.0, 0.0, 0.0, 0.0); + //shader_set_uniform_f(shader_get_uniform(_shader, BBMOD_U_LIGHT_AMBIENT_DIR_UP), 0.0, 0.0, 0.0); + } +} + +/// @macro {String} Name of a fragment shader uniform of type `vec3` that holds +/// the directional light's direction. +/// @see bbmod_light_directional_set +/// @see bbmod_light_directional_get +#macro BBMOD_U_LIGHT_DIRECTIONAL_DIR "bbmod_LightDirectionalDir" + +/// @macro {String} Name of a fragment shader uniform of type `vec4` that holds +/// the directional light's color in RGB and intensity in the A channel. +/// @see bbmod_light_directional_set +/// @see bbmod_light_directional_get +#macro BBMOD_U_LIGHT_DIRECTIONAL_COLOR "bbmod_LightDirectionalColor" + +/// @func bbmod_shader_set_directional_light(_shader[, _light[, _isLightmapped]) +/// +/// @desc Sets uniforms {@link BBMOD_U_LIGHT_DIRECTIONAL_DIR} and +/// {@link BBMOD_U_LIGHT_DIRECTIONAL_COLOR}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Struct.BBMOD_DirectionalLight} [_light] The directional light. +/// If `undefined`, then the value set by {@link bbmod_light_directional_set} +/// is used. If the light is not enabled then it is not passed. +/// @param {Bool} [_isLightmapped] Use `true` in case the shader renders +/// lightmapped models. Defaults to `false.` +/// +/// @see BBMOD_DirectionalLight +function bbmod_shader_set_directional_light(_shader, _light=undefined, _isLightmapped=false) +{ + gml_pragma("forceinline"); + _light ??= global.__bbmodDirectionalLight; + if (_light != undefined + && _light.Enabled + && (!_isLightmapped || _light.AffectLightmaps)) + { + var _direction = _light.Direction; + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_LIGHT_DIRECTIONAL_DIR), + _direction.X, + _direction.Y, + _direction.Z); + var _color = _light.Color; + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_LIGHT_DIRECTIONAL_COLOR), + _color.Red / 255.0, + _color.Green / 255.0, + _color.Blue / 255.0, + _color.Alpha); + } + else + { + shader_set_uniform_f(shader_get_uniform(_shader, BBMOD_U_LIGHT_DIRECTIONAL_DIR), 0.0, 0.0, -1.0); + shader_set_uniform_f(shader_get_uniform(_shader, BBMOD_U_LIGHT_DIRECTIONAL_COLOR), 0.0, 0.0, 0.0, 0.0); + } +} + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds the screen-space ambient occlusion texture. +#macro BBMOD_U_SSAO "bbmod_SSAO" + +/// @func bbmod_shader_set_ssao(_shader, _ssao) +/// +/// @desc Sets the {@link BBMOD_U_SSAO} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Pointer.Texture} _ssao The new SSAO texture. +function bbmod_shader_set_ssao(_shader, _ssao) +{ + gml_pragma("forceinline"); + texture_set_stage( + shader_get_sampler_index(_shader, BBMOD_U_SSAO), + _ssao); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether image based lighting is enabled (1.0) or disabled (0.0). +/// @see bbmod_ibl_set +/// @see bbmod_ibl_get +#macro BBMOD_U_IBL_ENABLE "bbmod_IBLEnable" + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds the image based lighting texture. +/// @see bbmod_ibl_set +/// @see bbmod_ibl_get +#macro BBMOD_U_IBL "bbmod_IBL" + +/// @macro {String} Name of a fragment shader uniform of type `vec2` that holds +/// the texel size of image based lighting texture. +/// @see bbmod_ibl_set +/// @see bbmod_ibl_get +#macro BBMOD_U_IBL_TEXEL "bbmod_IBLTexel" + +/// @func bbmod_shader_set_ibl(_shader[, _ibl[, _isLightmapped]]) +/// +/// @desc Sets a fragment shader uniforms {@link BBMOD_U_IBL_ENABLE}, +/// {@link BBMOD_U_IBL_TEXEL} and {@link BBMOD_U_IBL}. These are required for +/// image based lighting. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniforms for. +/// @param {Struct.BBMOD_ImageBasedLight} [_ibl] The image based light. +/// If `undefined`, then the value set by {@link bbmod_ibl_set} is used. If +/// the light is not enabled, then it is not passed. +/// @param {Bool} [_isLightmapped] Use `true` in case the shader renders +/// lightmapped models. Defaults to `false.` +function bbmod_shader_set_ibl(_shader, _ibl=undefined, _isLightmapped=false) +{ + gml_pragma("forceinline"); + + var _texture = pointer_null; + var _texel; + + _ibl ??= global.__bbmodImageBasedLight; + + if (_ibl != undefined + && _ibl.Enabled + && (!_isLightmapped || _ibl.AffectLightmaps)) + { + _texture = _ibl.Texture; + _texel = _ibl.Texel; + } + + if (global.__bbmodReflectionProbeTexture != pointer_null) + { + _texture = global.__bbmodReflectionProbeTexture; + _texel = texture_get_texel_height(_texture); + } + + if (_texture != pointer_null) + { + var _uIBL = shader_get_sampler_index(_shader, BBMOD_U_IBL); + + texture_set_stage(_uIBL, _texture); + gpu_set_tex_mip_enable_ext(_uIBL, mip_off) + gpu_set_tex_filter_ext(_uIBL, true); + gpu_set_tex_repeat_ext(_uIBL, false); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IBL_TEXEL), + _texel, _texel); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IBL_ENABLE), + 1.0); + } + else + { + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_IBL_ENABLE), + 0.0); + } +} + +/// @macro {String} Name of a fragment shader uniform of type +/// `vec4[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]` that holds vectors `(x, y, z, range)` +/// and `(r, g, b, intensity)` for each punctual light. +/// @see BBMOD_MAX_PUNCTUAL_LIGHTS +/// @see bbmod_light_punctual_add +#macro BBMOD_U_LIGHT_PUNCTUAL_DATA_A "bbmod_LightPunctualDataA" + +/// @macro {String} Name of a fragment shader uniform of type +/// `vec3[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]` that holds vectors +/// `(isSpotLight, dcosInner, dcosOuter)` and `(dirX, dirY, dirZ)` for each +/// punctual light. +/// @see BBMOD_MAX_PUNCTUAL_LIGHTS +/// @see bbmod_light_punctual_add +#macro BBMOD_U_LIGHT_PUNCTUAL_DATA_B "bbmod_LightPunctualDataB" + +/// @func bbmod_shader_set_punctual_lights(_shader[, _lights[, _isLightmapped]]) +/// +/// @desc Sets uniforms {@link BBMOD_U_LIGHT_PUNCTUAL_DATA_A} and +/// {@link BBMOD_U_LIGHT_PUNCTUAL_DATA_B}. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Array} [_lights] An array of punctual +/// lights. If `undefined`, then the lights defined using +/// {@link bbmod_light_punctual_add} are passed. Only enabled lights will be used! +/// @param {Bool} [_isLightmapped] Use `true` in case the shader renders +/// lightmapped models. Defaults to `false.` +function bbmod_shader_set_punctual_lights(_shader, _lights=undefined, _isLightmapped=false) +{ + gml_pragma("forceinline"); + + _lights ??= global.__bbmodPunctualLights; + + var _renderPassMask = (1 << bbmod_render_pass_get()); + + var _indexA = 0; + var _indexMaxA = BBMOD_MAX_PUNCTUAL_LIGHTS * 8; + var _dataA = array_create(_indexMaxA, 0.0); + + var _indexB = 0; + var _indexMaxB = BBMOD_MAX_PUNCTUAL_LIGHTS * 6; + var _dataB = array_create(_indexMaxB, 0.0); + + var i = 0; + + repeat (array_length(_lights)) + { + var _light = _lights[i++]; + + if (_light.Enabled + && (_light.RenderPass & _renderPassMask) != 0 + && (!_isLightmapped || _light.AffectLightmaps)) + { + _light.Position.ToArray(_dataA, _indexA); + _dataA[@ _indexA + 3] = _light.Range; + var _color = _light.Color; + _dataA[@ _indexA + 4] = _color.Red / 255.0; + _dataA[@ _indexA + 5] = _color.Green / 255.0; + _dataA[@ _indexA + 6] = _color.Blue / 255.0; + _dataA[@ _indexA + 7] = _color.Alpha; + _indexA += 8; + + if (is_instanceof(_light, BBMOD_SpotLight)) + { + _dataB[@ _indexB] = 1.0; + _dataB[@ _indexB + 1] = dcos(_light.AngleInner); + _dataB[@ _indexB + 2] = dcos(_light.AngleOuter); + _light.Direction.ToArray(_dataB, _indexB + 3); + } + _indexB += 6; + + if (_indexA >= _indexMaxA) + { + break; + } + } + } + + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_LIGHT_PUNCTUAL_DATA_A), + _dataA); + shader_set_uniform_f_array( + shader_get_uniform(_shader, BBMOD_U_LIGHT_PUNCTUAL_DATA_B), + _dataB); +} + +/// @macro {String} Common part of uniform names {@link BBMOD_U_TERRAIN_BASE_OPACITY_0}, +/// {@link BBMOD_U_TERRAIN_BASE_OPACITY_1} and {@link BBMOD_U_TERRAIN_BASE_OPACITY_2}, +/// which only append a number to it. +#macro BBMOD_U_TERRAIN_BASE_OPACITY "bbmod_TerrainBaseOpacity" + +/// @macro {String} Common part of uniform names {@link BBMOD_U_TERRAIN_NORMAL_W_0}, +/// {@link BBMOD_U_TERRAIN_NORMAL_W_1} and {@link BBMOD_U_TERRAIN_NORMAL_W_2}, +/// which only append a number to it. +#macro BBMOD_U_TERRAIN_NORMAL_W "bbmod_TerrainNormalW" + +/// @macro {String} Common part of uniform names {@link BBMOD_U_TERRAIN_IS_ROUGHNESS_0}, +/// {@link BBMOD_U_TERRAIN_IS_ROUGHNESS_1} and {@link BBMOD_U_TERRAIN_IS_ROUGHNESS_2}, +/// which only append a number to it. +#macro BBMOD_U_TERRAIN_IS_ROUGHNESS "bbmod_TerrainIsRoughness" + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with base color in RGB channels and opacity in the A channel +/// for the first terrain layer rendered in a single draw call. +#macro BBMOD_U_TERRAIN_BASE_OPACITY_0 "gm_BaseTexture" + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds normal smoothness/roughness texture for the first terrain layer rendered +/// in a single draw call. +#macro BBMOD_U_TERRAIN_NORMAL_W_0 (BBMOD_U_TERRAIN_NORMAL_W + "0") + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether the first terrain material layer uses roughness workflow (1.0) or not (0.0). +#macro BBMOD_U_TERRAIN_IS_ROUGHNESS_0 (BBMOD_U_TERRAIN_IS_ROUGHNESS + "0") + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with base color in RGB channels and opacity in the A channel +/// for the second terrain layer rendered in a single draw call. +#macro BBMOD_U_TERRAIN_BASE_OPACITY_1 (BBMOD_U_TERRAIN_BASE_OPACITY + "1") + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds normal smoothness/roughness texture for the second terrain layer rendered +/// in a single draw call. +#macro BBMOD_U_TERRAIN_NORMAL_W_1 (BBMOD_U_TERRAIN_NORMAL_W + "1") + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether the second terrain material layer uses roughness workflow (1.0) or not (0.0). +#macro BBMOD_U_TERRAIN_IS_ROUGHNESS_1 (BBMOD_U_TERRAIN_IS_ROUGHNESS + "1") + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds a texture with base color in RGB channels and opacity in the A channel +/// for the third terrain layer rendered in a single draw call. +#macro BBMOD_U_TERRAIN_BASE_OPACITY_2 (BBMOD_U_TERRAIN_BASE_OPACITY + "2") + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds normal smoothness/roughness texture for the third terrain layer rendered +/// in a single draw call. +#macro BBMOD_U_TERRAIN_NORMAL_W_2 (BBMOD_U_TERRAIN_NORMAL_W + "2") + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether the third terrain material layer uses roughness workflow (1.0) or not (0.0). +#macro BBMOD_U_TERRAIN_IS_ROUGHNESS_2 (BBMOD_U_TERRAIN_IS_ROUGHNESS + "2") + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds the splatmap texture. +#macro BBMOD_U_SPLATMAP "bbmod_Splatmap" + +/// @macro {String} Common part of uniform names {@link BBMOD_U_SPLATMAP_INDEX_0}, +/// {@link BBMOD_U_SPLATMAP_INDEX_1} and {@link BBMOD_U_SPLATMAP_INDEX_2}, +/// which only append a number to it. +#macro BBMOD_U_SPLATMAP_INDEX "bbmod_SplatmapIndex" + +/// @macro {String} Name of a fragment shader uniform of type `int` that holds +/// the index of a channel to read from the splatmap for the first terrain layer +/// rendered in a draw call. +#macro BBMOD_U_SPLATMAP_INDEX_0 (BBMOD_U_SPLATMAP_INDEX + "0") + +/// @macro {String} Name of a fragment shader uniform of type `int` that holds +/// the index of a channel to read from the splatmap for the second terrain layer +/// rendered in a draw call. +#macro BBMOD_U_SPLATMAP_INDEX_1 (BBMOD_U_SPLATMAP_INDEX + "1") + +/// @macro {String} Name of a fragment shader uniform of type `int` that holds +/// the index of a channel to read from the splatmap for the third terrain layer +/// rendered in a draw call. +#macro BBMOD_U_SPLATMAP_INDEX_2 (BBMOD_U_SPLATMAP_INDEX + "2") + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds the colormap texture. +#macro BBMOD_U_COLORMAP "bbmod_Colormap" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether shadowmapping is enabled (1.0) or disabled (0.0). +#macro BBMOD_U_SHADOWMAP_ENABLE_PS "bbmod_ShadowmapEnablePS" + +/// @macro {String} Name of a fragment shader uniform of type `sampler2D` that +/// holds the shadowmap texture. +#macro BBMOD_U_SHADOWMAP "bbmod_Shadowmap" + +/// @macro {String} Name of a fragment shader uniform of type `vec2` that holds +/// the texel size of a shadowmap texture. +#macro BBMOD_U_SHADOWMAP_TEXEL "bbmod_ShadowmapTexel" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the area that the shadowmap captures. +#macro BBMOD_U_SHADOWMAP_AREA "bbmod_ShadowmapArea" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the distance over which models smoothly transition into shadow. Useful for +/// example for volumetric look of particles. +#macro BBMOD_U_SHADOWMAP_BIAS "bbmod_ShadowmapBias" + +/// @func bbmod_shader_set_shadowmap_bias(_shader, _bias) +/// +/// @desc Sets the {@link BBMOD_U_SHADOWMAP_BIAS} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Real} _bias The new shadowmap bias value. +function bbmod_shader_set_shadowmap_bias(_shader, _bias) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_SHADOWMAP_BIAS), + _bias); +} + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// the index of a punctual light that casts shadows or -1.0, if it's the +/// directional light. +#macro BBMOD_U_SHADOW_CASTER_INDEX "bbmod_ShadowCasterIndex" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// how much are vertices offset by their normal before they are transformed into +/// shadowmap-space, using formula `vertex + normal * normalOffset`. +#macro BBMOD_U_SHADOWMAP_NORMAL_OFFSET_PS "bbmod_ShadowmapNormalOffsetPS" + +/// @macro {String} Name of a fragment shader uniform of type `float` that holds +/// whether HDR rendering is enabled (1.0) or not (0.0). +/// @see bbmod_hdr_is_supported +#macro BBMOD_U_HDR "bbmod_HDR" + +/// @funct bbmod_shader_set_hdr(_shader, _hdr) +/// +/// @desc Sets the {@link BBMOD_U_HDR} uniform. +/// +/// @param {Asset.GMShader} _shader The shader to set the uniform for. +/// @param {Bool} _hdr Use `true` when rendering into floating point surfaces. +function bbmod_shader_set_hdr(_shader, _hdr) +{ + gml_pragma("forceinline"); + shader_set_uniform_f( + shader_get_uniform(_shader, BBMOD_U_HDR), + _hdr ? 1.0 : 0.0); +} diff --git a/BBMOD_GML/scripts/__bbmod_shader_set/__bbmod_shader_set.yy b/BBMOD_GML/scripts/__bbmod_shader_set/__bbmod_shader_set.yy new file mode 100644 index 00000000..5b117371 --- /dev/null +++ b/BBMOD_GML/scripts/__bbmod_shader_set/__bbmod_shader_set.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "__bbmod_shader_set", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "Rendering", + "path": "folders/BBMOD/Core/Rendering.yy", + }, +} \ No newline at end of file diff --git a/BBMOD_GML/scripts/__bbmod_sky/__bbmod_sky.gml b/BBMOD_GML/scripts/__bbmod_sky/__bbmod_sky.gml index d88ef8d7..90a54613 100644 --- a/BBMOD_GML/scripts/__bbmod_sky/__bbmod_sky.gml +++ b/BBMOD_GML/scripts/__bbmod_sky/__bbmod_sky.gml @@ -12,12 +12,13 @@ function __bbmod_material_sky() if (_material == undefined) { var _skSky = new BBMOD_BaseShader(BBMOD_ShSky, BBMOD_VFORMAT_DEFAULT); - _material = new BBMOD_BaseMaterial(_skSky) + _material = new BBMOD_BaseMaterial() + .set_shader(BBMOD_ERenderPass.Background, _skSky) .set_shader(BBMOD_ERenderPass.ReflectionCapture, _skSky); _material.Culling = cull_noculling; _material.Mipmapping = mip_off; _material.ZWrite = false; - _material.ZTest = true; + _material.ZTest = false; _material.Filtering = true; _material.RenderQueue = _skyRenderQueue; } diff --git a/BBMOD_GML/scripts/__bbmod_ssao/__bbmod_ssao.gml b/BBMOD_GML/scripts/__bbmod_ssao/__bbmod_ssao.gml index cf87e83c..4c994b52 100644 --- a/BBMOD_GML/scripts/__bbmod_ssao/__bbmod_ssao.gml +++ b/BBMOD_GML/scripts/__bbmod_ssao/__bbmod_ssao.gml @@ -133,13 +133,12 @@ function bbmod_ssao_draw( static _uBlurClipFar = shader_get_uniform(BBMOD_ShSSAOBlur, "u_fClipFar"); static _uBlurDepthRange = shader_get_uniform(BBMOD_ShSSAOBlur, "u_fDepthRange"); - var _tanAspect = (_matProj[11] == 0.0) - ? [1.0, -1.0] // Ortho - : [1.0 / _matProj[0], -1.0 / _matProj[5]]; // Perspective + var _tanAspect = __bbmod_matrix_proj_get_tanaspect(_matProj); var _width = surface_get_width(_surSsao); var _height = surface_get_height(_surSsao); gpu_push_state(); + gpu_set_state(bbmod_gpu_get_default_state()); gpu_set_tex_repeat(false); static _cam = camera_create(); diff --git a/BBMOD_GML/scripts/__bbmod_terrain/__bbmod_terrain.gml b/BBMOD_GML/scripts/__bbmod_terrain/__bbmod_terrain.gml index a965d197..07e7fd71 100644 --- a/BBMOD_GML/scripts/__bbmod_terrain/__bbmod_terrain.gml +++ b/BBMOD_GML/scripts/__bbmod_terrain/__bbmod_terrain.gml @@ -1,12 +1,14 @@ /// @module Terrain -/// @macro {Struct.BBMOD_TerrainShader} Shader for terrain materials. +/// @macro {Struct.BBMOD_TerrainShader} Shader for terrain materials. Supports +/// up to 5 terrain layers, each one being rendered in its own draw call. #macro BBMOD_SHADER_TERRAIN __bbmod_shader_terrain() /// @macro {Struct.BBMOD_TerrainMaterial} Base terrain material. #macro BBMOD_MATERIAL_TERRAIN __bbmod_material_terrain() /// @macro {Struct.BBMOD_TerrainShader} Shader for unlit terrain materials. +/// Supports up to 5 material layers, rendering up to 3 in a single draw call. #macro BBMOD_SHADER_TERRAIN_UNLIT __bbmod_shader_terrain_unlit() /// @macro {Struct.BBMOD_BaseMaterial} Unlit terrain material. diff --git a/BBMOD_GML/scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.gml b/BBMOD_GML/scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.gml new file mode 100644 index 00000000..ac1e6008 --- /dev/null +++ b/BBMOD_GML/scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.gml @@ -0,0 +1,16 @@ +/// @module Core + +/// @func bbmod_hdr_is_supported() +/// +/// @desc Checks whether high dynamic range (HDR) rendering is supported on +/// the current platform. +/// +/// @return {Bool} Returns `true` if HDR rendering is supported on the current +/// platform. +function bbmod_hdr_is_supported() +{ + var _isSupported = surface_format_is_supported(surface_rgba16float); + return _isSupported; +} + +__bbmod_info("HDR is " + (!bbmod_hdr_is_supported() ? "NOT " : "") + "supported!"); diff --git a/BBMOD_GML/scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.yy b/BBMOD_GML/scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.yy new file mode 100644 index 00000000..e7813e79 --- /dev/null +++ b/BBMOD_GML/scripts/bbmod_hdr_is_supported/bbmod_hdr_is_supported.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "bbmod_hdr_is_supported", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "Utils", + "path": "folders/BBMOD/Core/Utils.yy", + }, +} \ No newline at end of file diff --git a/BBMOD_GML/scripts/bbmod_mrt_is_supported/bbmod_mrt_is_supported.gml b/BBMOD_GML/scripts/bbmod_mrt_is_supported/bbmod_mrt_is_supported.gml index 6ac48870..9100a3d5 100644 --- a/BBMOD_GML/scripts/bbmod_mrt_is_supported/bbmod_mrt_is_supported.gml +++ b/BBMOD_GML/scripts/bbmod_mrt_is_supported/bbmod_mrt_is_supported.gml @@ -13,24 +13,15 @@ function bbmod_mrt_is_supported() if (_isSupported == undefined) { - var _shader = __BBMOD_ShCheckMRT; + var _shader = BBMOD_ShCheckMRT; if (shader_is_compiled(_shader)) { - var _surface1 = bbmod_surface_check(-1, 1, 1, surface_rgba8unorm, false); - var _surface2 = bbmod_surface_check(-1, 1, 1, surface_rgba8unorm, false); + var _surface1 = surface_create(1, 1); + var _surface2 = surface_create(1, 1); surface_set_target_ext(0, _surface1); - surface_set_target_ext(1, _surface2); - draw_clear(c_black); - shader_set(_shader); - draw_sprite(BBMOD_SprWhite, 0, 0, 0); - shader_reset(); + _isSupported = surface_set_target_ext(1, _surface2); surface_reset_target(); - - var _pixel1 = surface_getpixel_ext(_surface1, 0, 0); - var _pixel2 = surface_getpixel_ext(_surface2, 0, 0); - _isSupported = (_pixel1 == $FFFFFFFF && _pixel2 == $FFFFFFFF); - surface_free(_surface1); surface_free(_surface2); } @@ -43,4 +34,4 @@ function bbmod_mrt_is_supported() return _isSupported; } -__bbmod_info("MRT " + (!bbmod_mrt_is_supported() ? "not " : "") + "supported!"); +__bbmod_info("MRT is " + (!bbmod_mrt_is_supported() ? "NOT " : "") + "supported!"); diff --git a/BBMOD_GML/scripts/bbmod_particleshader/bbmod_particleshader.gml b/BBMOD_GML/scripts/bbmod_particleshader/bbmod_particleshader.gml index c607e8d6..301e38ce 100644 --- a/BBMOD_GML/scripts/bbmod_particleshader/bbmod_particleshader.gml +++ b/BBMOD_GML/scripts/bbmod_particleshader/bbmod_particleshader.gml @@ -19,9 +19,7 @@ function BBMOD_ParticleShader(_shader, _vertexFormat) { gml_pragma("forceinline"); DefaultShader_set_material(_material); - shader_set_uniform_f( - shader_get_uniform(shader_current(), BBMOD_U_SOFT_DISTANCE), - _material.SoftDistance); + bbmod_shader_set_soft_distance(shader_current(), _material.SoftDistance); return self; }; } diff --git a/BBMOD_GML/scripts/bbmod_surface_check/bbmod_surface_check.gml b/BBMOD_GML/scripts/bbmod_surface_check/bbmod_surface_check.gml index 2b518def..2fea3809 100644 --- a/BBMOD_GML/scripts/bbmod_surface_check/bbmod_surface_check.gml +++ b/BBMOD_GML/scripts/bbmod_surface_check/bbmod_surface_check.gml @@ -2,14 +2,15 @@ /// @func bbmod_surface_check(_surface, _width, _height[, _format[, _depthBuffer]]) /// -/// @desc Checks whether the surface exists and if it has correct size. Broken -/// surfaces are recreated. Surfaces of wrong size are resized. +/// @desc Assures a surface has the correct size and format. Reallocates the surface +/// if it does not exist. /// /// @param {Id.Surface} _surface The surface to check. /// @param {Real} _width The desired width of the surface. /// @param {Real} _height The desired height of the surface. -/// @param {Real} [_format] The surface format to use when the surface is created. -/// Use one of the `surface_` constants. Defaults to `surface_rgba8unorm`. +/// @param {Constant.SurfaceFormatType} [_format] The surface format to use when +/// the surface is created. Use one of the `surface_` constants. Defaults to +/// `surface_rgba8unorm`. /// @param {Bool} [_depthBuffer] Whether to create a depth buffer for the surface. /// Defaults to `true`. /// @@ -18,11 +19,16 @@ function bbmod_surface_check(_surface, _width, _height, _format=surface_rgba8uno { _width = max(round(_width), 1); _height = max(round(_height), 1); - - if (!surface_exists(_surface)) + + if (!surface_exists(_surface) + || surface_get_format(_surface) != _format) { var _depthDisabled = surface_get_depth_disable(); surface_depth_disable(!_depthBuffer); + if (surface_exists(_surface)) + { + surface_free(_surface); + } _surface = surface_create(_width, _height, _format); surface_depth_disable(_depthDisabled); } diff --git a/BBMOD_GML/scripts/bbmod_vtf_is_supported/bbmod_vtf_is_supported.gml b/BBMOD_GML/scripts/bbmod_vtf_is_supported/bbmod_vtf_is_supported.gml index 40f5387d..502682c6 100644 --- a/BBMOD_GML/scripts/bbmod_vtf_is_supported/bbmod_vtf_is_supported.gml +++ b/BBMOD_GML/scripts/bbmod_vtf_is_supported/bbmod_vtf_is_supported.gml @@ -13,7 +13,7 @@ function bbmod_vtf_is_supported() if (_isSupported == undefined) { - var _shader = __BBMOD_ShCheckVTF; + var _shader = BBMOD_ShCheckVTF; if (shader_is_compiled(_shader)) { @@ -42,4 +42,4 @@ function bbmod_vtf_is_supported() return _isSupported; } -__bbmod_info("VTF " + (!bbmod_vtf_is_supported() ? "not " : "") + "supported!"); +__bbmod_info("VTF is " + (!bbmod_vtf_is_supported() ? "NOT " : "") + "supported!"); diff --git a/BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.fsh b/BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.fsh similarity index 94% rename from BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.fsh rename to BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.fsh index 6c2d64ca..2ce66889 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.fsh @@ -1,5 +1,5 @@ -void main() -{ - gl_FragData[0] = vec4(1.0); +void main() +{ + gl_FragData[0] = vec4(1.0); gl_FragData[1] = vec4(1.0); -} +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.vsh b/BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.vsh similarity index 95% rename from BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.vsh rename to BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.vsh index 976eb2e4..1fd8799b 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.vsh @@ -1,6 +1,6 @@ -attribute vec4 in_Position; +attribute vec4 in_Position; -void main() -{ - gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; -} +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.yy b/BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.yy similarity index 83% rename from BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.yy rename to BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.yy index 3fc6271b..e03ff2a7 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCheckMRT/__BBMOD_ShCheckMRT.yy +++ b/BBMOD_GML/shaders/BBMOD_ShCheckMRT/BBMOD_ShCheckMRT.yy @@ -1,7 +1,7 @@ { "resourceType": "GMShader", "resourceVersion": "1.0", - "name": "__BBMOD_ShCheckMRT", + "name": "BBMOD_ShCheckMRT", "parent": { "name": "Utils", "path": "folders/BBMOD/Core/Utils.yy", diff --git a/BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.fsh b/BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.fsh similarity index 91% rename from BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.fsh rename to BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.fsh index 3b276499..ead291a4 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.fsh @@ -1,6 +1,6 @@ -varying vec4 v_vColour; - -void main() -{ - gl_FragColor = v_vColour; -} +varying vec4 v_vColour; + +void main() +{ + gl_FragColor = v_vColour; +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.vsh b/BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.vsh similarity index 95% rename from BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.vsh rename to BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.vsh index b0062064..d24ad91a 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.vsh @@ -1,12 +1,12 @@ -attribute vec4 in_Position; -attribute vec2 in_TextureCoord; - -varying vec4 v_vColour; - -uniform sampler2D u_texTest; - -void main() -{ - gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; - v_vColour = texture2DLod(u_texTest, in_TextureCoord, 0.0); -} +attribute vec4 in_Position; +attribute vec2 in_TextureCoord; + +varying vec4 v_vColour; + +uniform sampler2D u_texTest; + +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + v_vColour = texture2DLod(u_texTest, in_TextureCoord, 0.0); +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.yy b/BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.yy similarity index 83% rename from BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.yy rename to BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.yy index 895d2b21..c2c6415b 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCheckVTF/__BBMOD_ShCheckVTF.yy +++ b/BBMOD_GML/shaders/BBMOD_ShCheckVTF/BBMOD_ShCheckVTF.yy @@ -1,7 +1,7 @@ { "resourceType": "GMShader", "resourceVersion": "1.0", - "name": "__BBMOD_ShCheckVTF", + "name": "BBMOD_ShCheckVTF", "parent": { "name": "Utils", "path": "folders/BBMOD/Core/Utils.yy", diff --git a/BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.fsh b/BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.fsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.fsh rename to BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.fsh diff --git a/BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.vsh b/BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.vsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.vsh rename to BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.vsh diff --git a/BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.yy b/BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.yy similarity index 80% rename from BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.yy rename to BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.yy index 141ad998..77160e23 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.yy +++ b/BBMOD_GML/shaders/BBMOD_ShCubemapToOctahedron/BBMOD_ShCubemapToOctahedron.yy @@ -1,7 +1,7 @@ { "resourceType": "GMShader", "resourceVersion": "1.0", - "name": "__BBMOD_ShPrefilterSpecular", + "name": "BBMOD_ShCubemapToOctahedron", "parent": { "name": "Rendering", "path": "folders/BBMOD/Core/Rendering.yy", diff --git a/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.fsh b/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.fsh index c94a17b6..1306d97e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.fsh @@ -139,6 +139,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -602,6 +610,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -701,19 +712,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -783,9 +807,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -814,5 +841,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.vsh b/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.vsh index f9e5248f..127acf0e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefault/BBMOD_ShDefault.vsh @@ -36,7 +36,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -110,6 +110,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.fsh index c94a17b6..1306d97e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.fsh @@ -139,6 +139,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -602,6 +610,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -701,19 +712,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -783,9 +807,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -814,5 +841,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.vsh b/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.vsh index d502dc61..fd6dc266 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultAnimated/BBMOD_ShDefaultAnimated.vsh @@ -41,7 +41,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -166,6 +166,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.fsh index c94a17b6..1306d97e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.fsh @@ -139,6 +139,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -602,6 +610,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -701,19 +712,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -783,9 +807,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -814,5 +841,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.vsh b/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.vsh index d5cc567b..b79e60b7 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultBatched/BBMOD_ShDefaultBatched.vsh @@ -40,7 +40,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -127,6 +127,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.fsh index bb03cf9d..c984ecaa 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.fsh @@ -141,6 +141,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -604,6 +612,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -703,19 +714,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -785,9 +809,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -819,5 +846,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.vsh b/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.vsh index 5992fa4b..116b5497 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultColor/BBMOD_ShDefaultColor.vsh @@ -38,7 +38,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -135,6 +135,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.fsh index bb03cf9d..c984ecaa 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.fsh @@ -141,6 +141,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -604,6 +612,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -703,19 +714,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -785,9 +809,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -819,5 +846,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.vsh b/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.vsh index 1d7a1f7e..a723a649 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultColorAnimated/BBMOD_ShDefaultColorAnimated.vsh @@ -43,7 +43,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -191,6 +191,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.fsh index bb03cf9d..c984ecaa 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.fsh @@ -141,6 +141,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -604,6 +612,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -703,19 +714,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -785,9 +809,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -819,5 +846,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.vsh b/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.vsh index a742a3f5..53f7ad76 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultColorBatched/BBMOD_ShDefaultColorBatched.vsh @@ -42,7 +42,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -152,6 +152,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepth/BBMOD_ShDefaultDepth.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepth/BBMOD_ShDefaultDepth.fsh index 570ee20a..da1665c8 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepth/BBMOD_ShDefaultDepth.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepth/BBMOD_ShDefaultDepth.fsh @@ -49,6 +49,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -99,6 +111,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthAnimated/BBMOD_ShDefaultDepthAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthAnimated/BBMOD_ShDefaultDepthAnimated.fsh index 570ee20a..da1665c8 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthAnimated/BBMOD_ShDefaultDepthAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthAnimated/BBMOD_ShDefaultDepthAnimated.fsh @@ -49,6 +49,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -99,6 +111,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthBatched/BBMOD_ShDefaultDepthBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthBatched/BBMOD_ShDefaultDepthBatched.fsh index 570ee20a..da1665c8 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthBatched/BBMOD_ShDefaultDepthBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthBatched/BBMOD_ShDefaultDepthBatched.fsh @@ -49,6 +49,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -99,6 +111,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColor/BBMOD_ShDefaultDepthColor.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColor/BBMOD_ShDefaultDepthColor.fsh index b4706cf9..1e730adc 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColor/BBMOD_ShDefaultDepthColor.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColor/BBMOD_ShDefaultDepthColor.fsh @@ -51,6 +51,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -101,6 +113,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorAnimated/BBMOD_ShDefaultDepthColorAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorAnimated/BBMOD_ShDefaultDepthColorAnimated.fsh index b4706cf9..1e730adc 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorAnimated/BBMOD_ShDefaultDepthColorAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorAnimated/BBMOD_ShDefaultDepthColorAnimated.fsh @@ -51,6 +51,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -101,6 +113,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorBatched/BBMOD_ShDefaultDepthColorBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorBatched/BBMOD_ShDefaultDepthColorBatched.fsh index b4706cf9..1e730adc 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorBatched/BBMOD_ShDefaultDepthColorBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthColorBatched/BBMOD_ShDefaultDepthColorBatched.fsh @@ -51,6 +51,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -101,6 +113,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthLightmap/BBMOD_ShDefaultDepthLightmap.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthLightmap/BBMOD_ShDefaultDepthLightmap.fsh index e1e3a168..4b497388 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultDepthLightmap/BBMOD_ShDefaultDepthLightmap.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultDepthLightmap/BBMOD_ShDefaultDepthLightmap.fsh @@ -50,6 +50,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -100,6 +112,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.fsh index 6b69d6d4..44addd22 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.fsh @@ -141,6 +141,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -198,17 +206,6 @@ Material CreateMaterial() m.Lightmap = vec3(0.0); return m; } -/// @param subsurface Color in RGB and thickness/intensity in A. -/// @source https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ -vec3 xCheapSubsurface(vec4 subsurface, vec3 eye, vec3 normal, vec3 light, vec3 lightColor) -{ - const float fLTPower = 1.0; - const float fLTScale = 1.0; - vec3 vLTLight = light + normal; - float fLTDot = pow(clamp(dot(eye, -vLTLight), 0.0, 1.0), fLTPower) * fLTScale; - float fLT = fLTDot * subsurface.a; - return subsurface.rgb * lightColor * fLT; -} #define X_PI 3.14159265359 #define X_2_PI 6.28318530718 @@ -601,6 +598,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -700,19 +700,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -783,9 +796,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -815,5 +831,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.vsh b/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.vsh index b5bcecd2..0b3bd616 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultLightmap/BBMOD_ShDefaultLightmap.vsh @@ -37,7 +37,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -113,6 +113,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultSprite/BBMOD_ShDefaultSprite.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultSprite/BBMOD_ShDefaultSprite.fsh index 7569d572..2b7e6dcd 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultSprite/BBMOD_ShDefaultSprite.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultSprite/BBMOD_ShDefaultSprite.fsh @@ -144,6 +144,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -607,6 +615,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -772,9 +783,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -806,5 +820,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlit/BBMOD_ShDefaultUnlit.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlit/BBMOD_ShDefaultUnlit.fsh index b42b2660..e9a33a86 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlit/BBMOD_ShDefaultUnlit.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlit/BBMOD_ShDefaultUnlit.fsh @@ -98,6 +98,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -280,9 +286,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -311,5 +321,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitAnimated/BBMOD_ShDefaultUnlitAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitAnimated/BBMOD_ShDefaultUnlitAnimated.fsh index b42b2660..e9a33a86 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitAnimated/BBMOD_ShDefaultUnlitAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitAnimated/BBMOD_ShDefaultUnlitAnimated.fsh @@ -98,6 +98,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -280,9 +286,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -311,5 +321,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitBatched/BBMOD_ShDefaultUnlitBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitBatched/BBMOD_ShDefaultUnlitBatched.fsh index b42b2660..e9a33a86 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitBatched/BBMOD_ShDefaultUnlitBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitBatched/BBMOD_ShDefaultUnlitBatched.fsh @@ -98,6 +98,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -280,9 +286,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -311,5 +321,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColor/BBMOD_ShDefaultUnlitColor.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColor/BBMOD_ShDefaultUnlitColor.fsh index 0c5fbc7f..2cb084c0 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColor/BBMOD_ShDefaultUnlitColor.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColor/BBMOD_ShDefaultUnlitColor.fsh @@ -100,6 +100,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -282,9 +288,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -316,5 +326,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorAnimated/BBMOD_ShDefaultUnlitColorAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorAnimated/BBMOD_ShDefaultUnlitColorAnimated.fsh index 0c5fbc7f..2cb084c0 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorAnimated/BBMOD_ShDefaultUnlitColorAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorAnimated/BBMOD_ShDefaultUnlitColorAnimated.fsh @@ -100,6 +100,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -282,9 +288,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -316,5 +326,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorBatched/BBMOD_ShDefaultUnlitColorBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorBatched/BBMOD_ShDefaultUnlitColorBatched.fsh index 0c5fbc7f..2cb084c0 100644 --- a/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorBatched/BBMOD_ShDefaultUnlitColorBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShDefaultUnlitColorBatched/BBMOD_ShDefaultUnlitColorBatched.fsh @@ -100,6 +100,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -282,9 +288,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -316,5 +326,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.fsh b/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.fsh new file mode 100644 index 00000000..239c1454 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.fsh @@ -0,0 +1,608 @@ +varying vec2 v_vTexCoord; + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +#define u_texGB0 gm_BaseTexture +uniform sampler2D u_texGB1; +uniform sampler2D u_texGB2; +uniform mat4 u_mView; +uniform mat4 u_mViewInverse; +uniform mat4 u_mProjection; +uniform vec2 u_vTanAspect; + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +// Ambient light's up vector. +uniform vec3 bbmod_LightAmbientDirUp; +// Ambient light color on the upper hemisphere. +uniform vec4 bbmod_LightAmbientUp; +// Ambient light color on the lower hemisphere. +uniform vec4 bbmod_LightAmbientDown; + +// Direction of the directional light +uniform vec3 bbmod_LightDirectionalDir; +// Color of the directional light +uniform vec4 bbmod_LightDirectionalColor; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnablePS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; +// Shadowmap texture +uniform sampler2D bbmod_Shadowmap; +// (1.0/shadowmapWidth, 1.0/shadowmapHeight) +uniform vec2 bbmod_ShadowmapTexel; +// The area that the shadowmap captures +uniform float bbmod_ShadowmapArea; +// The range over which meshes smoothly transition into shadow. +uniform float bbmod_ShadowmapBias; + +// 1.0 to enable IBL +uniform float bbmod_IBLEnable; +// Prefiltered octahedron env. map +uniform sampler2D bbmod_IBL; +// Texel size of one octahedron +uniform vec2 bbmod_IBLTexel; + +// SSAO texture +uniform sampler2D bbmod_SSAO; + +uniform float bbmod_HDR; + +#define F0_DEFAULT vec3(0.04) + +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} + +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @param subsurface Color in RGB and thickness/intensity in A. +/// @source https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ +vec3 xCheapSubsurface(vec4 subsurface, vec3 eye, vec3 normal, vec3 light, vec3 lightColor) +{ + const float fLTPower = 1.0; + const float fLTScale = 1.0; + vec3 vLTLight = light + normal; + float fLTDot = pow(clamp(dot(eye, -vLTLight), 0.0, 1.0), fLTPower) * fLTScale; + float fLT = fLTDot * subsurface.a; + return subsurface.rgb * lightColor * fLT; +} +#define X_PI 3.14159265359 +#define X_2_PI 6.28318530718 + +/// @return x^2 +#define xPow2(x) ((x) * (x)) + +/// @return x^3 +#define xPow3(x) ((x) * (x) * (x)) + +/// @return x^4 +#define xPow4(x) ((x) * (x) * (x) * (x)) + +/// @return x^5 +#define xPow5(x) ((x) * (x) * (x) * (x) * (x)) + +/// @return arctan2(x,y) +#define xAtan2(x, y) atan(y, x) + +/// @return Direction from point `from` to point `to` in degrees (0-360 range). +float xPointDirection(vec2 from, vec2 to) +{ + float x = xAtan2(from.x - to.x, from.y - to.y); + return ((x > 0.0) ? x : (2.0 * X_PI + x)) * 180.0 / X_PI; +} + +/// @desc Default specular color for dielectrics +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +#define X_F0_DEFAULT vec3(0.04, 0.04, 0.04) + +/// @desc Normal distribution function +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xSpecularD_GGX(float roughness, float NdotH) +{ + float r = xPow4(roughness); + float a = NdotH * NdotH * (r - 1.0) + 1.0; + return r / (X_PI * a * a); +} + +/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +float xSpecularD_Approx(float roughness, float RdotL) +{ + float a = roughness * roughness; + float a2 = a * a; + float rcp_a2 = 1.0 / a2; + // 0.5 / ln(2), 0.275 / ln(2) + float c = (0.72134752 * rcp_a2) + 0.39674113; + return (rcp_a2 * exp2((c * RdotL) - c)); +} + +/// @desc Roughness remapping for analytic lights. +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xK_Analytic(float roughness) +{ + return xPow2(roughness + 1.0) * 0.125; +} + +/// @desc Roughness remapping for IBL lights. +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xK_IBL(float roughness) +{ + return xPow2(roughness) * 0.5; +} + +/// @desc Geometric attenuation +/// @param k Use either xK_Analytic for analytic lights or xK_IBL for image based lighting. +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xSpecularG_Schlick(float k, float NdotL, float NdotV) +{ + return (NdotL / (NdotL * (1.0 - k) + k)) + * (NdotV / (NdotV * (1.0 - k) + k)); +} + +/// @desc Fresnel +/// @source https://en.wikipedia.org/wiki/Schlick%27s_approximation +vec3 xSpecularF_Schlick(vec3 f0, float VdotH) +{ + return f0 + (1.0 - f0) * xPow5(1.0 - VdotH); +} + +/// @desc Cook-Torrance microfacet specular shading +/// @note N = normalize(vertexNormal) +/// L = normalize(light - vertex) +/// V = normalize(camera - vertex) +/// H = normalize(L + V) +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +vec3 xBRDF(vec3 f0, float roughness, float NdotL, float NdotV, float NdotH, float VdotH) +{ + vec3 specular = xSpecularD_GGX(roughness, NdotH) + * xSpecularF_Schlick(f0, VdotH) + * xSpecularG_Schlick(xK_Analytic(roughness), NdotL, NdotH); + return specular / ((4.0 * NdotL * NdotV) + 0.1); +} + +vec3 SpecularGGX(Material m, vec3 N, vec3 V, vec3 L) +{ + vec3 H = normalize(L + V); + float NdotL = max(dot(N, L), 0.0); + float NdotV = max(dot(N, V), 0.0); + float NdotH = max(dot(N, H), 0.0); + float VdotH = max(dot(V, H), 0.0); + return xBRDF(m.Specular, m.Roughness, NdotL, NdotV, NdotH, VdotH); +} + +void DoDirectionalLightPS( + vec3 direction, + vec3 color, + float shadow, + vec3 vertex, + vec3 N, + vec3 V, + Material m, + inout vec3 diffuse, + inout vec3 specular, + inout vec3 subsurface) +{ + vec3 L = normalize(-direction); + float NdotL = max(dot(N, L), 0.0); + subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); + color *= (1.0 - shadow) * NdotL; + diffuse += color; + specular += color * SpecularGGX(m, N, V, L); +} + +void DoPointLightPS( + vec3 position, + float range, + vec3 color, + float shadow, + vec3 vertex, + vec3 N, + vec3 V, + Material m, + inout vec3 diffuse, + inout vec3 specular, + inout vec3 subsurface) +{ + vec3 L = position - vertex; + float dist = length(L); + L = normalize(L); + float att = clamp(1.0 - (dist / range), 0.0, 1.0); + att *= att; + float NdotL = max(dot(N, L), 0.0); + subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); + color *= (1.0 - shadow) * NdotL * att; + diffuse += color; + specular += color * SpecularGGX(m, N, V, L); +} + +void DoSpotLightPS( + vec3 position, + float range, + vec3 color, + float shadow, + vec3 direction, + float dcosInner, + float dcosOuter, + vec3 vertex, + vec3 N, + vec3 V, + Material m, + inout vec3 diffuse, + inout vec3 specular, + inout vec3 subsurface) +{ + vec3 L = position - vertex; + float dist = length(L); + L = normalize(L); + float att = clamp(1.0 - (dist / range), 0.0, 1.0); + float theta = dot(L, normalize(-direction)); + float epsilon = dcosInner - dcosOuter; + float intensity = clamp((theta - dcosOuter) / epsilon, 0.0, 1.0); + subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); + color *= (1.0 - shadow) * intensity * att; + diffuse += color; + specular += color * SpecularGGX(m, N, V, L); +} +void Exposure() +{ + gl_FragColor.rgb *= bbmod_Exposure * bbmod_Exposure; +} +void TonemapReinhard() +{ + gl_FragColor.rgb = gl_FragColor.rgb / (vec3(1.0) + gl_FragColor.rgb); +} + +//void Fog(float depth) +//{ +// vec3 ambientUp = xGammaToLinear(bbmod_LightAmbientUp.rgb) * bbmod_LightAmbientUp.a; +// vec3 ambientDown = xGammaToLinear(bbmod_LightAmbientDown.rgb) * bbmod_LightAmbientDown.a; +// vec3 directionalLightColor = xGammaToLinear(bbmod_LightDirectionalColor.rgb) * bbmod_LightDirectionalColor.a; +// vec3 fogColor = xGammaToLinear(bbmod_FogColor.rgb) * (ambientUp + ambientDown + directionalLightColor); +// float fogStrength = clamp((depth - bbmod_FogStart) * bbmod_FogRcpRange, 0.0, 1.0) * bbmod_FogColor.a; +// gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogStrength * bbmod_FogIntensity); +//} + +void GammaCorrect() +{ + gl_FragColor.rgb = xLinearToGamma(gl_FragColor.rgb); +} +// Source: https://gamedev.stackexchange.com/questions/169508/octahedral-impostors-octahedral-mapping + +/// @param dir Sampling dir vector in world-space. +/// @return UV coordinates on an octahedron map. +vec2 xVec3ToOctahedronUv(vec3 dir) +{ + vec3 octant = sign(dir); + float sum = dot(dir, octant); + vec3 octahedron = dir / sum; + if (octahedron.z < 0.0) + { + vec3 absolute = abs(octahedron); + octahedron.xy = octant.xy * vec2(1.0 - absolute.y, 1.0 - absolute.x); + } + return octahedron.xy * 0.5 + 0.5; +} + +/// @desc Converts octahedron UV into a world-space vector. +vec3 xOctahedronUvToVec3Normalized(vec2 uv) +{ + vec3 position = vec3(2.0 * (uv - 0.5), 0); + vec2 absolute = abs(position.xy); + position.z = 1.0 - absolute.x - absolute.y; + if (position.z < 0.0) + { + position.xy = sign(position.xy) * vec2(1.0 - absolute.y, 1.0 - absolute.x); + } + return position; +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +vec3 xDiffuseIBL(sampler2D ibl, vec2 texel, vec3 N) +{ + const float s = 1.0 / 8.0; + const float r2 = 7.0; + + vec2 uv0 = xVec3ToOctahedronUv(N); + uv0.x = (r2 + mix(texel.x, 1.0 - texel.x, uv0.x)) * s; + uv0.y = mix(texel.y, 1.0 - texel.y, uv0.y); + + return xGammaToLinear(xDecodeRGBM(texture2D(ibl, uv0))); +} + +/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +vec2 xEnvBRDFApprox(float roughness, float NdotV) +{ + const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); + const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); + vec4 r = (roughness * c0) + c1; + float a004 = (min(r.x * r.x, exp2(-9.28 * NdotV)) * r.x) + r.y; + return ((vec2(-1.04, 1.04) * a004) + r.zw); +} + +/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +float xEnvBRDFApproxNonmetal(float roughness, float NdotV) +{ + // Same as EnvBRDFApprox(0.04, Roughness, NdotV) + const vec2 c0 = vec2(-1.0, -0.0275); + const vec2 c1 = vec2(1.0, 0.0425); + vec2 r = (roughness * c0) + c1; + return (min(r.x * r.x, exp2(-9.28 * NdotV)) * r.x) + r.y; +} + +// Fully rough optimization: +// xEnvBRDFApprox(SpecularColor, 1, 1) == SpecularColor * 0.4524 - 0.0024 +// DiffuseColor += SpecularColor * 0.45; +// SpecularColor = 0.0; + +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +vec3 xSpecularIBL(sampler2D ibl, vec2 texel/*, sampler2D brdf*/, vec3 f0, float roughness, vec3 N, vec3 V) +{ + float NdotV = clamp(dot(N, V), 0.0, 1.0); + vec3 R = 2.0 * dot(V, N) * N - V; + // vec2 envBRDF = texture2D(brdf, vec2(roughness, NdotV)).xy; + vec2 envBRDF = xEnvBRDFApprox(roughness, NdotV); + + const float s = 1.0 / 8.0; + float r = roughness * 7.0; + float r2 = floor(r); + float rDiff = r - r2; + + vec2 uv0 = xVec3ToOctahedronUv(R); + uv0.x = (r2 + mix(texel.x, 1.0 - texel.x, uv0.x)) * s; + uv0.y = mix(texel.y, 1.0 - texel.y, uv0.y); + + vec2 uv1 = uv0; + uv1.x = uv1.x + s; + + vec3 specular = f0 * envBRDF.x + envBRDF.y; + + vec3 col0 = xGammaToLinear(xDecodeRGBM(texture2D(ibl, uv0))) * specular; + vec3 col1 = xGammaToLinear(xDecodeRGBM(texture2D(ibl, uv1))) * specular; + + return mix(col0, col1, rDiff); +} + +/// @param tanAspect (tanFovY*(screenWidth/screenHeight),-tanFovY), where +/// tanFovY = dtan(fov*0.5) +/// @param texCoord Sceen-space UV. +/// @param depth Scene depth at texCoord. +/// @return Point projected to view-space. +vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) +{ +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif + return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); +} + +/// @param p A point in clip space (transformed by projection matrix, but not +/// normalized). +/// @return P's UV coordinates on the screen. +vec2 xUnproject(vec4 p) +{ + vec2 uv = p.xy / p.w; + uv = uv * 0.5 + 0.5; +#if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + uv.y = 1.0 - uv.y; +#endif + return uv; +} +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +// Shadowmap filtering source: https://www.gamedev.net/tutorials/programming/graphics/contact-hardening-soft-shadows-made-fast-r4906/ +float InterleavedGradientNoise(vec2 positionScreen) +{ + vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189); + return fract(magic.z * fract(dot(positionScreen, magic.xy))); +} +vec2 VogelDiskSample(int sampleIndex, int samplesCount, float phi) +{ + float GoldenAngle = 2.4; + float r = sqrt(float(sampleIndex) + 0.5) / sqrt(float(samplesCount)); + float theta = float(sampleIndex) * GoldenAngle + phi; + float sine = sin(theta); + float cosine = cos(theta); + return vec2(r * cosine, r * sine); +} + +float ShadowMap(sampler2D shadowMap, vec2 texel, vec2 uv, float compareZ) +{ + if (clamp(uv.xy, vec2(0.0), vec2(1.0)) != uv.xy) + { + return 0.0; + } + float shadow = 0.0; + float noise = 6.28 * InterleavedGradientNoise(gl_FragCoord.xy); + float bias = bbmod_ShadowmapBias / bbmod_ShadowmapArea; + for (int i = 0; i < SHADOWMAP_SAMPLE_COUNT; ++i) + { + vec2 uv2 = uv + VogelDiskSample(i, SHADOWMAP_SAMPLE_COUNT, noise) * texel * 4.0; + float depth = xDecodeDepth(texture2D(shadowMap, uv2).rgb); + if (bias != 0.0) + { + shadow += clamp((compareZ - depth) / bias, 0.0, 1.0); + } + else + { + shadow += step(depth, compareZ); + } + } + return (shadow / float(SHADOWMAP_SAMPLE_COUNT)); +} + +void main() +{ + vec4 GB0 = texture2D(u_texGB0, v_vTexCoord); + vec4 GB1 = texture2D(u_texGB1, v_vTexCoord); + vec4 GB2 = texture2D(u_texGB2, v_vTexCoord); + + Material material = CreateMaterial(); + material.Base = xGammaToLinear(GB0.rgb); + material.AO = GB0.a; + material.Normal = normalize(GB1.rgb * 2.0 - 1.0); + material.Roughness = GB1.a; + material.Metallic = GB2.a; + material.Specular = material.Base * material.Metallic; + material.Base *= 1.0 - material.Metallic; + + float depth = xDecodeDepth(GB2.rgb) * bbmod_ZFar; + vec3 vertexView = xProject(u_vTanAspect, v_vTexCoord, depth); + vec3 vertexWorld = (u_mViewInverse * vec4(vertexView, 1.0)).xyz; + + vec4 v_vEye; + v_vEye.xyz = normalize(-vec3( + u_mView[0][2], + u_mView[1][2], + u_mView[2][2] + )); + v_vEye.w = (u_mProjection[2][3] == 0.0) ? 1.0 : 0.0; + + vec3 N = material.Normal; + vec3 V = (v_vEye.w == 1.0) ? v_vEye.xyz : normalize(bbmod_CamPos - vertexWorld); + vec3 lightDiffuse = vec3(0.0); + vec3 lightSpecular = vec3(0.0); + vec3 lightSubsurface = vec3(0.0); + + // Ambient light + vec3 ambientUp = xGammaToLinear(bbmod_LightAmbientUp.rgb) * bbmod_LightAmbientUp.a; + vec3 ambientDown = xGammaToLinear(bbmod_LightAmbientDown.rgb) * bbmod_LightAmbientDown.a; + lightDiffuse += mix(ambientDown, ambientUp, dot(N, bbmod_LightAmbientDirUp) * 0.5 + 0.5); + + // Shadow mapping + float shadow = 0.0; + if (bbmod_ShadowmapEnablePS == 1.0) + { + vec3 shadowmapPos = (bbmod_ShadowmapMatrix * vec4(vertexWorld + N * bbmod_ShadowmapNormalOffsetPS, 1.0)).xyz; + float shadowmapAtt = clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0); + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + + // IBL + if (bbmod_IBLEnable == 1.0) + { + lightDiffuse += xDiffuseIBL(bbmod_IBL, bbmod_IBLTexel, N); + lightSpecular += xSpecularIBL(bbmod_IBL, bbmod_IBLTexel, material.Specular, material.Roughness, N, V); + } + + // Directional light + vec3 directionalLightColor = xGammaToLinear(bbmod_LightDirectionalColor.rgb) * bbmod_LightDirectionalColor.a; + DoDirectionalLightPS( + bbmod_LightDirectionalDir, + directionalLightColor, + shadow, + vertexWorld, N, V, material, lightDiffuse, lightSpecular, lightSubsurface); + + // SSAO + float ssao = texture2D(bbmod_SSAO, v_vTexCoord).r; + lightDiffuse *= ssao; + lightSpecular *= ssao; + + gl_FragColor = vec4(((material.Base * lightDiffuse) + lightSpecular) * material.AO, 1.0); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.vsh b/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.vsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.vsh rename to BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.vsh diff --git a/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.yy b/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.yy new file mode 100644 index 00000000..643f35ce --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShDeferredFullscreen/BBMOD_ShDeferredFullscreen.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShDeferredFullscreen", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.fsh b/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.fsh new file mode 100644 index 00000000..0cc5f112 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.fsh @@ -0,0 +1,602 @@ +varying vec4 v_vVertex; + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +#define u_texGB0 gm_BaseTexture +uniform sampler2D u_texGB1; +uniform sampler2D u_texGB2; +uniform mat4 u_mView; +uniform mat4 u_mViewInverse; +uniform mat4 u_mProjection; +uniform vec2 u_vTanAspect; + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnablePS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; +// Shadowmap texture +uniform sampler2D bbmod_Shadowmap; +// (1.0/shadowmapWidth, 1.0/shadowmapHeight) +uniform vec2 bbmod_ShadowmapTexel; +// The area that the shadowmap captures +uniform float bbmod_ShadowmapArea; +// The range over which meshes smoothly transition into shadow. +uniform float bbmod_ShadowmapBias; + +uniform vec3 bbmod_LightPosition; +uniform float bbmod_LightRange; +uniform vec4 bbmod_LightColor; +uniform float bbmod_LightIsSpot; +uniform vec3 bbmod_LightDirection; +uniform float bbmod_LightInner; +uniform float bbmod_LightOuter; + +uniform float bbmod_HDR; + +#define F0_DEFAULT vec3(0.04) + +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} + +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @param subsurface Color in RGB and thickness/intensity in A. +/// @source https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ +vec3 xCheapSubsurface(vec4 subsurface, vec3 eye, vec3 normal, vec3 light, vec3 lightColor) +{ + const float fLTPower = 1.0; + const float fLTScale = 1.0; + vec3 vLTLight = light + normal; + float fLTDot = pow(clamp(dot(eye, -vLTLight), 0.0, 1.0), fLTPower) * fLTScale; + float fLT = fLTDot * subsurface.a; + return subsurface.rgb * lightColor * fLT; +} +#define X_PI 3.14159265359 +#define X_2_PI 6.28318530718 + +/// @return x^2 +#define xPow2(x) ((x) * (x)) + +/// @return x^3 +#define xPow3(x) ((x) * (x) * (x)) + +/// @return x^4 +#define xPow4(x) ((x) * (x) * (x) * (x)) + +/// @return x^5 +#define xPow5(x) ((x) * (x) * (x) * (x) * (x)) + +/// @return arctan2(x,y) +#define xAtan2(x, y) atan(y, x) + +/// @return Direction from point `from` to point `to` in degrees (0-360 range). +float xPointDirection(vec2 from, vec2 to) +{ + float x = xAtan2(from.x - to.x, from.y - to.y); + return ((x > 0.0) ? x : (2.0 * X_PI + x)) * 180.0 / X_PI; +} + +/// @desc Default specular color for dielectrics +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +#define X_F0_DEFAULT vec3(0.04, 0.04, 0.04) + +/// @desc Normal distribution function +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xSpecularD_GGX(float roughness, float NdotH) +{ + float r = xPow4(roughness); + float a = NdotH * NdotH * (r - 1.0) + 1.0; + return r / (X_PI * a * a); +} + +/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +float xSpecularD_Approx(float roughness, float RdotL) +{ + float a = roughness * roughness; + float a2 = a * a; + float rcp_a2 = 1.0 / a2; + // 0.5 / ln(2), 0.275 / ln(2) + float c = (0.72134752 * rcp_a2) + 0.39674113; + return (rcp_a2 * exp2((c * RdotL) - c)); +} + +/// @desc Roughness remapping for analytic lights. +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xK_Analytic(float roughness) +{ + return xPow2(roughness + 1.0) * 0.125; +} + +/// @desc Roughness remapping for IBL lights. +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xK_IBL(float roughness) +{ + return xPow2(roughness) * 0.5; +} + +/// @desc Geometric attenuation +/// @param k Use either xK_Analytic for analytic lights or xK_IBL for image based lighting. +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +float xSpecularG_Schlick(float k, float NdotL, float NdotV) +{ + return (NdotL / (NdotL * (1.0 - k) + k)) + * (NdotV / (NdotV * (1.0 - k) + k)); +} + +/// @desc Fresnel +/// @source https://en.wikipedia.org/wiki/Schlick%27s_approximation +vec3 xSpecularF_Schlick(vec3 f0, float VdotH) +{ + return f0 + (1.0 - f0) * xPow5(1.0 - VdotH); +} + +/// @desc Cook-Torrance microfacet specular shading +/// @note N = normalize(vertexNormal) +/// L = normalize(light - vertex) +/// V = normalize(camera - vertex) +/// H = normalize(L + V) +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +vec3 xBRDF(vec3 f0, float roughness, float NdotL, float NdotV, float NdotH, float VdotH) +{ + vec3 specular = xSpecularD_GGX(roughness, NdotH) + * xSpecularF_Schlick(f0, VdotH) + * xSpecularG_Schlick(xK_Analytic(roughness), NdotL, NdotH); + return specular / ((4.0 * NdotL * NdotV) + 0.1); +} + +vec3 SpecularGGX(Material m, vec3 N, vec3 V, vec3 L) +{ + vec3 H = normalize(L + V); + float NdotL = max(dot(N, L), 0.0); + float NdotV = max(dot(N, V), 0.0); + float NdotH = max(dot(N, H), 0.0); + float VdotH = max(dot(V, H), 0.0); + return xBRDF(m.Specular, m.Roughness, NdotL, NdotV, NdotH, VdotH); +} + +void DoDirectionalLightPS( + vec3 direction, + vec3 color, + float shadow, + vec3 vertex, + vec3 N, + vec3 V, + Material m, + inout vec3 diffuse, + inout vec3 specular, + inout vec3 subsurface) +{ + vec3 L = normalize(-direction); + float NdotL = max(dot(N, L), 0.0); + subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); + color *= (1.0 - shadow) * NdotL; + diffuse += color; + specular += color * SpecularGGX(m, N, V, L); +} + +void DoPointLightPS( + vec3 position, + float range, + vec3 color, + float shadow, + vec3 vertex, + vec3 N, + vec3 V, + Material m, + inout vec3 diffuse, + inout vec3 specular, + inout vec3 subsurface) +{ + vec3 L = position - vertex; + float dist = length(L); + L = normalize(L); + float att = clamp(1.0 - (dist / range), 0.0, 1.0); + att *= att; + //float att = xPow2(clamp(1.0 - xPow4(dist / range), 0.0, 1.0)) / (xPow2(dist) + 1.0); + float NdotL = max(dot(N, L), 0.0); + subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); + color *= (1.0 - shadow) * NdotL * att; + diffuse += color; + specular += color * SpecularGGX(m, N, V, L); +} + +void DoSpotLightPS( + vec3 position, + float range, + vec3 color, + float shadow, + vec3 direction, + float dcosInner, + float dcosOuter, + vec3 vertex, + vec3 N, + vec3 V, + Material m, + inout vec3 diffuse, + inout vec3 specular, + inout vec3 subsurface) +{ + vec3 L = position - vertex; + float dist = length(L); + L = normalize(L); + float att = clamp(1.0 - (dist / range), 0.0, 1.0); + float theta = dot(L, normalize(-direction)); + float epsilon = dcosInner - dcosOuter; + float intensity = clamp((theta - dcosOuter) / epsilon, 0.0, 1.0); + subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); + color *= (1.0 - shadow) * intensity * att; + diffuse += color; + specular += color * SpecularGGX(m, N, V, L); +} +void Exposure() +{ + gl_FragColor.rgb *= bbmod_Exposure * bbmod_Exposure; +} +void TonemapReinhard() +{ + gl_FragColor.rgb = gl_FragColor.rgb / (vec3(1.0) + gl_FragColor.rgb); +} + +//void Fog(float depth) +//{ +// vec3 ambientUp = xGammaToLinear(bbmod_LightAmbientUp.rgb) * bbmod_LightAmbientUp.a; +// vec3 ambientDown = xGammaToLinear(bbmod_LightAmbientDown.rgb) * bbmod_LightAmbientDown.a; +// vec3 directionalLightColor = xGammaToLinear(bbmod_LightDirectionalColor.rgb) * bbmod_LightDirectionalColor.a; +// vec3 fogColor = xGammaToLinear(bbmod_FogColor.rgb) * (ambientUp + ambientDown + directionalLightColor); +// float fogStrength = clamp((depth - bbmod_FogStart) * bbmod_FogRcpRange, 0.0, 1.0) * bbmod_FogColor.a; +// gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogStrength * bbmod_FogIntensity); +//} + +void GammaCorrect() +{ + gl_FragColor.rgb = xLinearToGamma(gl_FragColor.rgb); +} +// Source: https://gamedev.stackexchange.com/questions/169508/octahedral-impostors-octahedral-mapping + +/// @param dir Sampling dir vector in world-space. +/// @return UV coordinates on an octahedron map. +vec2 xVec3ToOctahedronUv(vec3 dir) +{ + vec3 octant = sign(dir); + float sum = dot(dir, octant); + vec3 octahedron = dir / sum; + if (octahedron.z < 0.0) + { + vec3 absolute = abs(octahedron); + octahedron.xy = octant.xy * vec2(1.0 - absolute.y, 1.0 - absolute.x); + } + return octahedron.xy * 0.5 + 0.5; +} + +/// @desc Converts octahedron UV into a world-space vector. +vec3 xOctahedronUvToVec3Normalized(vec2 uv) +{ + vec3 position = vec3(2.0 * (uv - 0.5), 0); + vec2 absolute = abs(position.xy); + position.z = 1.0 - absolute.x - absolute.y; + if (position.z < 0.0) + { + position.xy = sign(position.xy) * vec2(1.0 - absolute.y, 1.0 - absolute.x); + } + return position; +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +vec3 xDiffuseIBL(sampler2D ibl, vec2 texel, vec3 N) +{ + const float s = 1.0 / 8.0; + const float r2 = 7.0; + + vec2 uv0 = xVec3ToOctahedronUv(N); + uv0.x = (r2 + mix(texel.x, 1.0 - texel.x, uv0.x)) * s; + uv0.y = mix(texel.y, 1.0 - texel.y, uv0.y); + + return xGammaToLinear(xDecodeRGBM(texture2D(ibl, uv0))); +} + +/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +vec2 xEnvBRDFApprox(float roughness, float NdotV) +{ + const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); + const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); + vec4 r = (roughness * c0) + c1; + float a004 = (min(r.x * r.x, exp2(-9.28 * NdotV)) * r.x) + r.y; + return ((vec2(-1.04, 1.04) * a004) + r.zw); +} + +/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +float xEnvBRDFApproxNonmetal(float roughness, float NdotV) +{ + // Same as EnvBRDFApprox(0.04, Roughness, NdotV) + const vec2 c0 = vec2(-1.0, -0.0275); + const vec2 c1 = vec2(1.0, 0.0425); + vec2 r = (roughness * c0) + c1; + return (min(r.x * r.x, exp2(-9.28 * NdotV)) * r.x) + r.y; +} + +// Fully rough optimization: +// xEnvBRDFApprox(SpecularColor, 1, 1) == SpecularColor * 0.4524 - 0.0024 +// DiffuseColor += SpecularColor * 0.45; +// SpecularColor = 0.0; + +/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf +vec3 xSpecularIBL(sampler2D ibl, vec2 texel/*, sampler2D brdf*/, vec3 f0, float roughness, vec3 N, vec3 V) +{ + float NdotV = clamp(dot(N, V), 0.0, 1.0); + vec3 R = 2.0 * dot(V, N) * N - V; + // vec2 envBRDF = texture2D(brdf, vec2(roughness, NdotV)).xy; + vec2 envBRDF = xEnvBRDFApprox(roughness, NdotV); + + const float s = 1.0 / 8.0; + float r = roughness * 7.0; + float r2 = floor(r); + float rDiff = r - r2; + + vec2 uv0 = xVec3ToOctahedronUv(R); + uv0.x = (r2 + mix(texel.x, 1.0 - texel.x, uv0.x)) * s; + uv0.y = mix(texel.y, 1.0 - texel.y, uv0.y); + + vec2 uv1 = uv0; + uv1.x = uv1.x + s; + + vec3 specular = f0 * envBRDF.x + envBRDF.y; + + vec3 col0 = xGammaToLinear(xDecodeRGBM(texture2D(ibl, uv0))) * specular; + vec3 col1 = xGammaToLinear(xDecodeRGBM(texture2D(ibl, uv1))) * specular; + + return mix(col0, col1, rDiff); +} + +/// @param tanAspect (tanFovY*(screenWidth/screenHeight),-tanFovY), where +/// tanFovY = dtan(fov*0.5) +/// @param texCoord Sceen-space UV. +/// @param depth Scene depth at texCoord. +/// @return Point projected to view-space. +vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) +{ +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif + return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); +} + +/// @param p A point in clip space (transformed by projection matrix, but not +/// normalized). +/// @return P's UV coordinates on the screen. +vec2 xUnproject(vec4 p) +{ + vec2 uv = p.xy / p.w; + uv = uv * 0.5 + 0.5; +#if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + uv.y = 1.0 - uv.y; +#endif + return uv; +} +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +// Shadowmap filtering source: https://www.gamedev.net/tutorials/programming/graphics/contact-hardening-soft-shadows-made-fast-r4906/ +float InterleavedGradientNoise(vec2 positionScreen) +{ + vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189); + return fract(magic.z * fract(dot(positionScreen, magic.xy))); +} +vec2 VogelDiskSample(int sampleIndex, int samplesCount, float phi) +{ + float GoldenAngle = 2.4; + float r = sqrt(float(sampleIndex) + 0.5) / sqrt(float(samplesCount)); + float theta = float(sampleIndex) * GoldenAngle + phi; + float sine = sin(theta); + float cosine = cos(theta); + return vec2(r * cosine, r * sine); +} + +float ShadowMap(sampler2D shadowMap, vec2 texel, vec2 uv, float compareZ) +{ + if (clamp(uv.xy, vec2(0.0), vec2(1.0)) != uv.xy) + { + return 0.0; + } + float shadow = 0.0; + float noise = 6.28 * InterleavedGradientNoise(gl_FragCoord.xy); + float bias = bbmod_ShadowmapBias / bbmod_ShadowmapArea; + for (int i = 0; i < SHADOWMAP_SAMPLE_COUNT; ++i) + { + vec2 uv2 = uv + VogelDiskSample(i, SHADOWMAP_SAMPLE_COUNT, noise) * texel * 4.0; + float depth = xDecodeDepth(texture2D(shadowMap, uv2).rgb); + if (bias != 0.0) + { + shadow += clamp((compareZ - depth) / bias, 0.0, 1.0); + } + else + { + shadow += step(depth, compareZ); + } + } + return (shadow / float(SHADOWMAP_SAMPLE_COUNT)); +} + +void main() +{ + vec2 screenUV = xUnproject(v_vVertex); + vec4 GB0 = texture2D(u_texGB0, screenUV); + vec4 GB1 = texture2D(u_texGB1, screenUV); + vec4 GB2 = texture2D(u_texGB2, screenUV); + + Material material = CreateMaterial(); + material.Base = xGammaToLinear(GB0.rgb); + material.AO = GB0.a; + material.Normal = normalize(GB1.rgb * 2.0 - 1.0); + material.Roughness = GB1.a; + material.Metallic = GB2.a; + material.Specular = material.Base * material.Metallic; + material.Base *= 1.0 - material.Metallic; + + float depth = xDecodeDepth(GB2.rgb) * bbmod_ZFar; + vec3 vertexView = xProject(u_vTanAspect, screenUV, depth); + vec3 vertexWorld = (u_mViewInverse * vec4(vertexView, 1.0)).xyz; + + vec4 v_vEye; + v_vEye.xyz = normalize(-vec3( + u_mView[0][2], + u_mView[1][2], + u_mView[2][2] + )); + v_vEye.w = (u_mProjection[2][3] == 0.0) ? 1.0 : 0.0; + + vec3 N = material.Normal; + vec3 V = (v_vEye.w == 1.0) ? v_vEye.xyz : normalize(bbmod_CamPos - vertexWorld); + vec3 lightDiffuse = vec3(0.0); + vec3 lightSpecular = vec3(0.0); + vec3 lightSubsurface = vec3(0.0); + + // Shadow mapping + float shadow = 0.0; + if (bbmod_ShadowmapEnablePS == 1.0) + { + if (bbmod_LightIsSpot == 1.0) + { + vec4 shadowmapPos = bbmod_ShadowmapMatrix * vec4(vertexWorld + N * bbmod_ShadowmapNormalOffsetPS, 1.0); + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 lightVec = bbmod_LightPosition - vertexWorld; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } + } + + // Light + vec3 lightColor = xGammaToLinear(bbmod_LightColor.rgb) * bbmod_LightColor.a; + + if (bbmod_LightIsSpot == 1.0) + { + DoSpotLightPS( + bbmod_LightPosition, bbmod_LightRange, lightColor, + shadow, + bbmod_LightDirection, bbmod_LightInner, bbmod_LightOuter, + vertexWorld, N, V, material, + lightDiffuse, lightSpecular, lightSubsurface); + } + else + { + DoPointLightPS( + bbmod_LightPosition, bbmod_LightRange, lightColor, + shadow, + vertexWorld, N, V, material, + lightDiffuse, lightSpecular, lightSubsurface); + } + + gl_FragColor = vec4(((material.Base * lightDiffuse) + lightSpecular) * material.AO, 1.0); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.vsh b/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.vsh new file mode 100644 index 00000000..fe779091 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.vsh @@ -0,0 +1,12 @@ +attribute vec4 in_Position; +//attribute vec3 in_Normal; +//attribute vec2 in_TextureCoord0; +//attribute vec4 in_TangentW; + +varying vec4 v_vVertex; + +void main() +{ + v_vVertex = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + gl_Position = v_vVertex; +} diff --git a/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.yy b/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.yy new file mode 100644 index 00000000..b744ba81 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShDeferredPunctual/BBMOD_ShDeferredPunctual.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShDeferredPunctual", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShExtractSplatmapLayer/BBMOD_ShExtractSplatmapLayer.yy b/BBMOD_GML/shaders/BBMOD_ShExtractSplatmapLayer/BBMOD_ShExtractSplatmapLayer.yy index 2721a883..09749405 100644 --- a/BBMOD_GML/shaders/BBMOD_ShExtractSplatmapLayer/BBMOD_ShExtractSplatmapLayer.yy +++ b/BBMOD_GML/shaders/BBMOD_ShExtractSplatmapLayer/BBMOD_ShExtractSplatmapLayer.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShExtractSplatmapLayer", "parent": { - "name": "Terrain", - "path": "folders/BBMOD/Terrain.yy", + "name": "Shaders", + "path": "folders/BBMOD/Terrain/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.fsh b/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.fsh new file mode 100644 index 00000000..c139c45e --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.fsh @@ -0,0 +1,68 @@ +varying vec2 v_vTexCoord; + +// Distance to the far clipping plane +uniform float bbmod_ZFar; + +// The color of the fog +uniform vec4 bbmod_FogColor; +// Maximum fog intensity +uniform float bbmod_FogIntensity; +// Distance at which the fog starts +uniform float bbmod_FogStart; +// 1.0 / (fogEnd - fogStart) +uniform float bbmod_FogRcpRange; + +// Ambient light's up vector. +uniform vec3 bbmod_LightAmbientDirUp; +// Ambient light color on the upper hemisphere. +uniform vec4 bbmod_LightAmbientUp; +// Ambient light color on the lower hemisphere. +uniform vec4 bbmod_LightAmbientDown; + +// Direction of the directional light +uniform vec3 bbmod_LightDirectionalDir; +// Color of the directional light +uniform vec4 bbmod_LightDirectionalColor; + +uniform sampler2D u_texDepth; + +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} + +void Fog(float depth) +{ + vec3 ambientUp = xGammaToLinear(bbmod_LightAmbientUp.rgb) * bbmod_LightAmbientUp.a; + vec3 ambientDown = xGammaToLinear(bbmod_LightAmbientDown.rgb) * bbmod_LightAmbientDown.a; + vec3 directionalLightColor = xGammaToLinear(bbmod_LightDirectionalColor.rgb) * bbmod_LightDirectionalColor.a; + vec3 fogColor = xGammaToLinear(bbmod_FogColor.rgb) * (ambientUp + ambientDown + directionalLightColor); + float fogStrength = clamp((depth - bbmod_FogStart) * bbmod_FogRcpRange, 0.0, 1.0) * bbmod_FogColor.a; + gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogStrength * bbmod_FogIntensity); +} + +void main() +{ + float depth = xDecodeDepth(texture2D(u_texDepth, v_vTexCoord).rgb) * bbmod_ZFar; + gl_FragColor = vec4(texture2D(gm_BaseTexture, v_vTexCoord).rgb, (depth > 0.0) ? 1.0 : 0.0); + Fog(depth); +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.vsh b/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.vsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.vsh rename to BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.vsh diff --git a/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.yy b/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.yy new file mode 100644 index 00000000..ce1c4948 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShFogAndDepthMask/BBMOD_ShFogAndDepthMask.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShFogAndDepthMask", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.fsh b/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.fsh new file mode 100644 index 00000000..f5ed0554 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.fsh @@ -0,0 +1,309 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.vsh b/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.vsh new file mode 100644 index 00000000..d7f496cb --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.vsh @@ -0,0 +1,115 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_TangentW; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.yy b/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.yy new file mode 100644 index 00000000..ae290f92 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBuffer/BBMOD_ShGBuffer.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBuffer", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.fsh new file mode 100644 index 00000000..f5ed0554 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.fsh @@ -0,0 +1,309 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.vsh new file mode 100644 index 00000000..1e286fba --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.vsh @@ -0,0 +1,171 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_TangentW; + +attribute vec4 in_BoneIndex; +attribute vec4 in_BoneWeight; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +uniform vec4 bbmod_Bones[2 * BBMOD_MAX_BONES]; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +vec3 QuaternionRotate(vec4 q, vec3 v) +{ + return (v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v)); +} + +vec3 DualQuaternionTransform(vec4 real, vec4 dual, vec3 v) +{ + return (QuaternionRotate(real, v) + + 2.0 * (real.w * dual.xyz - dual.w * real.xyz + cross(real.xyz, dual.xyz))); +} + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + + // Source: + // https://www.cs.utah.edu/~ladislav/kavan07skinning/kavan07skinning.pdf + // https://www.cs.utah.edu/~ladislav/dq/dqs.cg + ivec4 i = ivec4(in_BoneIndex) * 2; + ivec4 j = i + 1; + + vec4 real0 = bbmod_Bones[i.x]; + vec4 real1 = bbmod_Bones[i.y]; + vec4 real2 = bbmod_Bones[i.z]; + vec4 real3 = bbmod_Bones[i.w]; + + vec4 dual0 = bbmod_Bones[j.x]; + vec4 dual1 = bbmod_Bones[j.y]; + vec4 dual2 = bbmod_Bones[j.z]; + vec4 dual3 = bbmod_Bones[j.w]; + + if (dot(real0, real1) < 0.0) { real1 *= -1.0; dual1 *= -1.0; } + if (dot(real0, real2) < 0.0) { real2 *= -1.0; dual2 *= -1.0; } + if (dot(real0, real3) < 0.0) { real3 *= -1.0; dual3 *= -1.0; } + + vec4 blendReal = + real0 * in_BoneWeight.x + + real1 * in_BoneWeight.y + + real2 * in_BoneWeight.z + + real3 * in_BoneWeight.w; + + vec4 blendDual = + dual0 * in_BoneWeight.x + + dual1 * in_BoneWeight.y + + dual2 * in_BoneWeight.z + + dual3 * in_BoneWeight.w; + + float len = length(blendReal); + blendReal /= len; + blendDual /= len; + + vertex = vec4(DualQuaternionTransform(blendReal, blendDual, vertex.xyz), 1.0); + normal = QuaternionRotate(blendReal, normal); + tangent = QuaternionRotate(blendReal, tangent); + bitangent = QuaternionRotate(blendReal, bitangent); + + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.yy new file mode 100644 index 00000000..35d887e4 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferAnimated/BBMOD_ShGBufferAnimated.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferAnimated", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.fsh new file mode 100644 index 00000000..f5ed0554 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.fsh @@ -0,0 +1,309 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.vsh new file mode 100644 index 00000000..08875fb6 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.vsh @@ -0,0 +1,132 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_TangentW; + +attribute float in_Id; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +uniform vec4 bbmod_BatchData[BBMOD_MAX_BATCH_VEC4S]; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +vec3 QuaternionRotate(vec4 q, vec3 v) +{ + return (v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v)); +} + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); + + int idx = int(in_Id) * 3; + vec4 posScale = bbmod_BatchData[idx]; + vec4 rot = bbmod_BatchData[idx + 1]; + + vertex = vec4(posScale.xyz + (QuaternionRotate(rot, vertex.xyz) * posScale.w), 1.0); + normal = QuaternionRotate(rot, normal); + tangent = QuaternionRotate(rot, tangent); + bitangent = QuaternionRotate(rot, bitangent); + +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.yy new file mode 100644 index 00000000..7035adc0 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferBatched/BBMOD_ShGBufferBatched.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferBatched", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.fsh new file mode 100644 index 00000000..94d06e72 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.fsh @@ -0,0 +1,314 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec4 v_vColor; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= v_vColor.rgb; + material.Opacity *= v_vColor.a; + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.vsh new file mode 100644 index 00000000..94411ed6 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.vsh @@ -0,0 +1,140 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_Color; + +attribute vec4 in_TangentW; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec4 v_vColor; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); +} + +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vColor = vec4(xGammaToLinear(in_Color.rgb), in_Color.a); + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.yy new file mode 100644 index 00000000..4b4cb125 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColor/BBMOD_ShGBufferColor.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferColor", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.fsh new file mode 100644 index 00000000..94d06e72 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.fsh @@ -0,0 +1,314 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec4 v_vColor; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= v_vColor.rgb; + material.Opacity *= v_vColor.a; + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.vsh new file mode 100644 index 00000000..2f6c9f86 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.vsh @@ -0,0 +1,196 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_Color; + +attribute vec4 in_TangentW; + +attribute vec4 in_BoneIndex; +attribute vec4 in_BoneWeight; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +uniform vec4 bbmod_Bones[2 * BBMOD_MAX_BONES]; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec4 v_vColor; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +vec3 QuaternionRotate(vec4 q, vec3 v) +{ + return (v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v)); +} + +vec3 DualQuaternionTransform(vec4 real, vec4 dual, vec3 v) +{ + return (QuaternionRotate(real, v) + + 2.0 * (real.w * dual.xyz - dual.w * real.xyz + cross(real.xyz, dual.xyz))); +} + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + + // Source: + // https://www.cs.utah.edu/~ladislav/kavan07skinning/kavan07skinning.pdf + // https://www.cs.utah.edu/~ladislav/dq/dqs.cg + ivec4 i = ivec4(in_BoneIndex) * 2; + ivec4 j = i + 1; + + vec4 real0 = bbmod_Bones[i.x]; + vec4 real1 = bbmod_Bones[i.y]; + vec4 real2 = bbmod_Bones[i.z]; + vec4 real3 = bbmod_Bones[i.w]; + + vec4 dual0 = bbmod_Bones[j.x]; + vec4 dual1 = bbmod_Bones[j.y]; + vec4 dual2 = bbmod_Bones[j.z]; + vec4 dual3 = bbmod_Bones[j.w]; + + if (dot(real0, real1) < 0.0) { real1 *= -1.0; dual1 *= -1.0; } + if (dot(real0, real2) < 0.0) { real2 *= -1.0; dual2 *= -1.0; } + if (dot(real0, real3) < 0.0) { real3 *= -1.0; dual3 *= -1.0; } + + vec4 blendReal = + real0 * in_BoneWeight.x + + real1 * in_BoneWeight.y + + real2 * in_BoneWeight.z + + real3 * in_BoneWeight.w; + + vec4 blendDual = + dual0 * in_BoneWeight.x + + dual1 * in_BoneWeight.y + + dual2 * in_BoneWeight.z + + dual3 * in_BoneWeight.w; + + float len = length(blendReal); + blendReal /= len; + blendDual /= len; + + vertex = vec4(DualQuaternionTransform(blendReal, blendDual, vertex.xyz), 1.0); + normal = QuaternionRotate(blendReal, normal); + tangent = QuaternionRotate(blendReal, tangent); + bitangent = QuaternionRotate(blendReal, bitangent); + + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); +} + +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vColor = vec4(xGammaToLinear(in_Color.rgb), in_Color.a); + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.yy new file mode 100644 index 00000000..7fba4892 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColorAnimated/BBMOD_ShGBufferColorAnimated.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferColorAnimated", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.fsh new file mode 100644 index 00000000..94d06e72 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.fsh @@ -0,0 +1,314 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec4 v_vColor; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= v_vColor.rgb; + material.Opacity *= v_vColor.a; + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.vsh new file mode 100644 index 00000000..73fdaaff --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.vsh @@ -0,0 +1,157 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_Color; + +attribute vec4 in_TangentW; + +attribute float in_Id; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +uniform vec4 bbmod_BatchData[BBMOD_MAX_BATCH_VEC4S]; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec4 v_vColor; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +vec3 QuaternionRotate(vec4 q, vec3 v) +{ + return (v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v)); +} + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); + + int idx = int(in_Id) * 3; + vec4 posScale = bbmod_BatchData[idx]; + vec4 rot = bbmod_BatchData[idx + 1]; + + vertex = vec4(posScale.xyz + (QuaternionRotate(rot, vertex.xyz) * posScale.w), 1.0); + normal = QuaternionRotate(rot, normal); + tangent = QuaternionRotate(rot, tangent); + bitangent = QuaternionRotate(rot, bitangent); + +} + +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vColor = vec4(xGammaToLinear(in_Color.rgb), in_Color.a); + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.yy new file mode 100644 index 00000000..69251163 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferColorBatched/BBMOD_ShGBufferColorBatched.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferColorBatched", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.fsh new file mode 100644 index 00000000..d96bfe0f --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.fsh @@ -0,0 +1,7 @@ +varying vec2 v_vTexCoord; + +void main() +{ + vec4 gb = texture2D(gm_BaseTexture, v_vTexCoord); + gl_FragColor = vec4(vec3(gb.a), 1.0); +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.vsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.vsh rename to BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.vsh diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.yy new file mode 100644 index 00000000..6db233bc --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractA/BBMOD_ShGBufferExtractA.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferExtractA", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.fsh new file mode 100644 index 00000000..a44c6d40 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.fsh @@ -0,0 +1,7 @@ +varying vec2 v_vTexCoord; + +void main() +{ + vec4 gb = texture2D(gm_BaseTexture, v_vTexCoord); + gl_FragColor = vec4(gb.rgb, 1.0); +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.vsh new file mode 100644 index 00000000..6a6ea8ca --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.vsh @@ -0,0 +1,10 @@ +attribute vec4 in_Position; +attribute vec2 in_TextureCoord; + +varying vec2 v_vTexCoord; + +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + v_vTexCoord = in_TextureCoord; +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.yy new file mode 100644 index 00000000..402cc6d1 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferExtractRGB/BBMOD_ShGBufferExtractRGB.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferExtractRGB", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.fsh b/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.fsh new file mode 100644 index 00000000..bfc49acd --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.fsh @@ -0,0 +1,397 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec2 v_vSplatmapCoord; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// Terrain + +// First layer: +// RGB: Base color, A: Opacity +#define bbmod_TerrainBaseOpacity0 gm_BaseTexture +// If 1.0 then the material uses roughness +uniform float bbmod_TerrainIsRoughness0; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_TerrainNormalW0; +// Splatmap channel to read. Use -1 for none. +uniform int bbmod_SplatmapIndex0; + +// Splatmap texture +uniform sampler2D bbmod_Splatmap; +// Colormap texture +uniform sampler2D bbmod_Colormap; + +// Second layer: +// RGB: Base color, A: Opacity +uniform sampler2D bbmod_TerrainBaseOpacity1; +// If 1.0 then the material uses roughness +uniform float bbmod_TerrainIsRoughness1; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_TerrainNormalW1; +// Splatmap channel to read. Use -1 for none. +uniform int bbmod_SplatmapIndex1; + +// Third layer: +// RGB: Base color, A: Opacity +uniform sampler2D bbmod_TerrainBaseOpacity2; +// If 1.0 then the material uses roughness +uniform float bbmod_TerrainIsRoughness2; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_TerrainNormalW2; +// Splatmap channel to read. Use -1 for none. +uniform int bbmod_SplatmapIndex2; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + m.Metallic = 0.0; + m.AO = 1.0; + m.Specular = F0_DEFAULT; + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_TerrainBaseOpacity0, + bbmod_TerrainIsRoughness0, + bbmod_TerrainNormalW0, + v_mTBN, + v_vTexCoord); + + Material material1 = UnpackMaterial( + bbmod_TerrainBaseOpacity1, + bbmod_TerrainIsRoughness1, + bbmod_TerrainNormalW1, + v_mTBN, + v_vTexCoord); + + Material material2 = UnpackMaterial( + bbmod_TerrainBaseOpacity2, + bbmod_TerrainIsRoughness2, + bbmod_TerrainNormalW2, + v_mTBN, + v_vTexCoord); + + // Splatmap + vec4 splatmap = texture2D(bbmod_Splatmap, v_vSplatmapCoord); + + // Blend layers + if (bbmod_SplatmapIndex0 >= 0) + { + // splatmap[index] does not work in HTML5 + float layerStrength = ((bbmod_SplatmapIndex0 == 0) ? splatmap.r + : ((bbmod_SplatmapIndex0 == 1) ? splatmap.g + : ((bbmod_SplatmapIndex0 == 2) ? splatmap.b + : splatmap.a))); + + material.Opacity *= layerStrength; + } + + if (bbmod_SplatmapIndex1 >= 0) + { + // splatmap[index] does not work in HTML5 + float layerStrength = ((bbmod_SplatmapIndex1 == 0) ? splatmap.r + : ((bbmod_SplatmapIndex1 == 1) ? splatmap.g + : ((bbmod_SplatmapIndex1 == 2) ? splatmap.b + : splatmap.a))); + float layerStrengthInv = 1.0 - layerStrength; + + material.Base *= layerStrengthInv; + material.Opacity *= layerStrengthInv; + + material.Base += layerStrength * material1.Base; + material.Opacity += layerStrength * material1.Opacity; + + material.Normal *= layerStrengthInv; + material.Metallic *= layerStrengthInv; + material.Roughness *= layerStrengthInv; + material.Specular *= layerStrengthInv; + material.Smoothness *= layerStrengthInv; + material.SpecularPower *= layerStrengthInv; + material.AO *= layerStrengthInv; + material.Emissive *= layerStrengthInv; + material.Subsurface *= layerStrengthInv; + material.Lightmap *= layerStrengthInv; + + material.Normal += layerStrength * material1.Normal; + material.Metallic += layerStrength * material1.Metallic; + material.Roughness += layerStrength * material1.Roughness; + material.Specular += layerStrength * material1.Specular; + material.Smoothness += layerStrength * material1.Smoothness; + material.SpecularPower += layerStrength * material1.SpecularPower; + material.AO += layerStrength * material1.AO; + material.Emissive += layerStrength * material1.Emissive; + material.Subsurface += layerStrength * material1.Subsurface; + material.Lightmap += layerStrength * material1.Lightmap; + } + + if (bbmod_SplatmapIndex2 >= 0) + { + // splatmap[index] does not work in HTML5 + float layerStrength= ((bbmod_SplatmapIndex2 == 0) ? splatmap.r + : ((bbmod_SplatmapIndex2 == 1) ? splatmap.g + : ((bbmod_SplatmapIndex2 == 2) ? splatmap.b + : splatmap.a))); + float layerStrengthInv = 1.0 - layerStrength; + + material.Base *= layerStrengthInv; + material.Opacity *= layerStrengthInv; + + material.Base += layerStrength * material2.Base; + material.Opacity += layerStrength * material2.Opacity; + + material.Normal *= layerStrengthInv; + material.Metallic *= layerStrengthInv; + material.Roughness *= layerStrengthInv; + material.Specular *= layerStrengthInv; + material.Smoothness *= layerStrengthInv; + material.SpecularPower *= layerStrengthInv; + material.AO *= layerStrengthInv; + material.Emissive *= layerStrengthInv; + material.Subsurface *= layerStrengthInv; + material.Lightmap *= layerStrengthInv; + + material.Normal += layerStrength * material2.Normal; + material.Metallic += layerStrength * material2.Metallic; + material.Roughness += layerStrength * material2.Roughness; + material.Specular += layerStrength * material2.Specular; + material.Smoothness += layerStrength * material2.Smoothness; + material.SpecularPower += layerStrength * material2.SpecularPower; + material.AO += layerStrength * material2.AO; + material.Emissive += layerStrength * material2.Emissive; + material.Subsurface += layerStrength * material2.Subsurface; + material.Lightmap += layerStrength * material2.Lightmap; + } + + // Colormap + material.Base *= xGammaToLinear(texture2D(bbmod_Colormap, v_vSplatmapCoord).xyz); + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(material.Normal * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.vsh b/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.vsh new file mode 100644 index 00000000..60a8553b --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.vsh @@ -0,0 +1,120 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_TangentW; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// +uniform mat4 bbmod_NormalMatrix; + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec2 v_vSplatmapCoord; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((bbmod_NormalMatrix * vec4(normal, 0.0)).xyz); + tangent = normalize((bbmod_NormalMatrix * vec4(tangent, 0.0)).xyz); + bitangent = normalize((bbmod_NormalMatrix * vec4(bitangent, 0.0)).xyz); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + v_vSplatmapCoord = in_TextureCoord0; + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.yy b/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.yy new file mode 100644 index 00000000..a582d0af --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShGBufferTerrain/BBMOD_ShGBufferTerrain.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShGBufferTerrain", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGizmo/BBMOD_ShGizmo.yy b/BBMOD_GML/shaders/BBMOD_ShGizmo/BBMOD_ShGizmo.yy index 698bc34e..e52f3f59 100644 --- a/BBMOD_GML/shaders/BBMOD_ShGizmo/BBMOD_ShGizmo.yy +++ b/BBMOD_GML/shaders/BBMOD_ShGizmo/BBMOD_ShGizmo.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShGizmo", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy b/BBMOD_GML/shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy index 2ad0b958..efa4536f 100644 --- a/BBMOD_GML/shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy +++ b/BBMOD_GML/shaders/BBMOD_ShGizmoSelect/BBMOD_ShGizmoSelect.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShGizmoSelect", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.fsh b/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.fsh new file mode 100644 index 00000000..2aecfb1d --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.fsh @@ -0,0 +1,34 @@ +varying vec2 v_vTexCoord; + +uniform float bbmod_Exposure; + +#define X_GAMMA 2.2 + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +void Exposure() +{ + gl_FragColor.rgb *= bbmod_Exposure * bbmod_Exposure; +} + +void TonemapReinhard() +{ + gl_FragColor.rgb = gl_FragColor.rgb / (vec3(1.0) + gl_FragColor.rgb); +} + +void GammaCorrect() +{ + gl_FragColor.rgb = xLinearToGamma(gl_FragColor.rgb); +} + +void main() +{ + gl_FragColor = texture2D(gm_BaseTexture, v_vTexCoord); + Exposure(); + TonemapReinhard(); + GammaCorrect(); +} diff --git a/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.vsh b/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.vsh new file mode 100644 index 00000000..6a6ea8ca --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.vsh @@ -0,0 +1,10 @@ +attribute vec4 in_Position; +attribute vec2 in_TextureCoord; + +varying vec2 v_vTexCoord; + +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + v_vTexCoord = in_TextureCoord; +} diff --git a/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.yy b/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.yy new file mode 100644 index 00000000..18297e10 --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShHDRToSDR/BBMOD_ShHDRToSDR.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "BBMOD_ShHDRToSDR", + "parent": { + "name": "Shaders", + "path": "folders/BBMOD/DeferredRenderer/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceHighlight/BBMOD_ShInstanceHighlight.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceHighlight/BBMOD_ShInstanceHighlight.yy index aaa41b11..8892344e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceHighlight/BBMOD_ShInstanceHighlight.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceHighlight/BBMOD_ShInstanceHighlight.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceHighlight", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.fsh index 765b251d..2b21d221 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.fsh @@ -87,6 +87,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.yy index 54366e5e..d707b481 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceID/BBMOD_ShInstanceID.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceID", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.fsh index 765b251d..2b21d221 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.fsh @@ -87,6 +87,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy index 961284c0..bcf54d6e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDAnimated/BBMOD_ShInstanceIDAnimated.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceIDAnimated", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.fsh index 99216d40..27e1bda4 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.fsh @@ -83,6 +83,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy index 1cadccfe..a3f6cf4e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDBatched/BBMOD_ShInstanceIDBatched.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceIDBatched", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.fsh index fddbe15c..dbf4b374 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.fsh @@ -89,6 +89,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.yy index 278a6e35..336e142f 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColor/BBMOD_ShInstanceIDColor.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceIDColor", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.fsh index fddbe15c..dbf4b374 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.fsh @@ -89,6 +89,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.yy index 0a912733..f1bdf3c5 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorAnimated/BBMOD_ShInstanceIDColorAnimated.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceIDColorAnimated", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.fsh index 741fe228..45a9e4c8 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.fsh @@ -85,6 +85,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy index 64cf7cd3..18016d8e 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDColorBatched/BBMOD_ShInstanceIDColorBatched.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceIDColorBatched", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.fsh b/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.fsh index dffede43..09e9fd81 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.fsh @@ -88,6 +88,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes diff --git a/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.yy b/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.yy index f134b87f..b6b592fe 100644 --- a/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.yy +++ b/BBMOD_GML/shaders/BBMOD_ShInstanceIDLightmap/BBMOD_ShInstanceIDLightmap.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShInstanceIDLightmap", "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Shaders", + "path": "folders/BBMOD/Gizmo/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.fsh b/BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.fsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.fsh rename to BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.fsh diff --git a/BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.vsh b/BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.vsh new file mode 100644 index 00000000..6a6ea8ca --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.vsh @@ -0,0 +1,10 @@ +attribute vec4 in_Position; +attribute vec2 in_TextureCoord; + +varying vec2 v_vTexCoord; + +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + v_vTexCoord = in_TextureCoord; +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.yy b/BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.yy similarity index 84% rename from BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.yy rename to BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.yy index e9a08353..99d6c055 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShMixRGBM/__BBMOD_ShMixRGBM.yy +++ b/BBMOD_GML/shaders/BBMOD_ShMixRGBM/BBMOD_ShMixRGBM.yy @@ -1,7 +1,7 @@ { "resourceType": "GMShader", "resourceVersion": "1.0", - "name": "__BBMOD_ShMixRGBM", + "name": "BBMOD_ShMixRGBM", "parent": { "name": "Rendering", "path": "folders/BBMOD/Core/Rendering.yy", diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.fsh b/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.fsh index b4706cf9..1e730adc 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.fsh @@ -51,6 +51,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -101,6 +113,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.yy b/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.yy index 62a1310d..9e861959 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.yy +++ b/BBMOD_GML/shaders/BBMOD_ShParticleDepth/BBMOD_ShParticleDepth.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShParticleDepth", "parent": { - "name": "Particles", - "path": "folders/BBMOD/Particles.yy", + "name": "Shaders", + "path": "folders/BBMOD/Particles/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.fsh b/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.fsh index 9ebfa08b..502ae7bf 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.fsh @@ -151,6 +151,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -208,118 +216,19 @@ Material CreateMaterial() m.Lightmap = vec3(0.0); return m; } -/// @param subsurface Color in RGB and thickness/intensity in A. -/// @source https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ -vec3 xCheapSubsurface(vec4 subsurface, vec3 eye, vec3 normal, vec3 light, vec3 lightColor) -{ - const float fLTPower = 1.0; - const float fLTScale = 1.0; - vec3 vLTLight = light + normal; - float fLTDot = pow(clamp(dot(eye, -vLTLight), 0.0, 1.0), fLTPower) * fLTScale; - float fLT = fLTDot * subsurface.a; - return subsurface.rgb * lightColor * fLT; -} -#define X_PI 3.14159265359 -#define X_2_PI 6.28318530718 - -/// @return x^2 -#define xPow2(x) ((x) * (x)) - -/// @return x^3 -#define xPow3(x) ((x) * (x) * (x)) - -/// @return x^4 -#define xPow4(x) ((x) * (x) * (x) * (x)) - -/// @return x^5 -#define xPow5(x) ((x) * (x) * (x) * (x) * (x)) - -/// @return arctan2(x,y) -#define xAtan2(x, y) atan(y, x) - -/// @return Direction from point `from` to point `to` in degrees (0-360 range). -float xPointDirection(vec2 from, vec2 to) -{ - float x = xAtan2(from.x - to.x, from.y - to.y); - return ((x > 0.0) ? x : (2.0 * X_PI + x)) * 180.0 / X_PI; -} - -/// @desc Default specular color for dielectrics -/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf -#define X_F0_DEFAULT vec3(0.04, 0.04, 0.04) - -/// @desc Normal distribution function -/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf -float xSpecularD_GGX(float roughness, float NdotH) -{ - float r = xPow4(roughness); - float a = NdotH * NdotH * (r - 1.0) + 1.0; - return r / (X_PI * a * a); -} - -/// @source https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile -float xSpecularD_Approx(float roughness, float RdotL) -{ - float a = roughness * roughness; - float a2 = a * a; - float rcp_a2 = 1.0 / a2; - // 0.5 / ln(2), 0.275 / ln(2) - float c = (0.72134752 * rcp_a2) + 0.39674113; - return (rcp_a2 * exp2((c * RdotL) - c)); -} - -/// @desc Roughness remapping for analytic lights. -/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf -float xK_Analytic(float roughness) -{ - return xPow2(roughness + 1.0) * 0.125; -} -/// @desc Roughness remapping for IBL lights. -/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf -float xK_IBL(float roughness) -{ - return xPow2(roughness) * 0.5; -} - -/// @desc Geometric attenuation -/// @param k Use either xK_Analytic for analytic lights or xK_IBL for image based lighting. -/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf -float xSpecularG_Schlick(float k, float NdotL, float NdotV) -{ - return (NdotL / (NdotL * (1.0 - k) + k)) - * (NdotV / (NdotV * (1.0 - k) + k)); -} - -/// @desc Fresnel -/// @source https://en.wikipedia.org/wiki/Schlick%27s_approximation -vec3 xSpecularF_Schlick(vec3 f0, float VdotH) -{ - return f0 + (1.0 - f0) * xPow5(1.0 - VdotH); -} - -/// @desc Cook-Torrance microfacet specular shading -/// @note N = normalize(vertexNormal) -/// L = normalize(light - vertex) -/// V = normalize(camera - vertex) -/// H = normalize(L + V) -/// @source http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf -vec3 xBRDF(vec3 f0, float roughness, float NdotL, float NdotV, float NdotH, float VdotH) -{ - vec3 specular = xSpecularD_GGX(roughness, NdotH) - * xSpecularF_Schlick(f0, VdotH) - * xSpecularG_Schlick(xK_Analytic(roughness), NdotL, NdotH); - return specular / ((4.0 * NdotL * NdotV) + 0.1); -} - -vec3 SpecularGGX(Material m, vec3 N, vec3 V, vec3 L) +vec3 SpecularBlinnPhong(Material m, vec3 N, vec3 V, vec3 L) { vec3 H = normalize(L + V); - float NdotL = max(dot(N, L), 0.0); - float NdotV = max(dot(N, V), 0.0); float NdotH = max(dot(N, H), 0.0); float VdotH = max(dot(V, H), 0.0); - return xBRDF(m.Specular, m.Roughness, NdotL, NdotV, NdotH, VdotH); + vec3 fresnel = m.Specular + (1.0 - m.Specular) * pow(1.0 - VdotH, 5.0); + float visibility = 0.25; + float A = m.SpecularPower / log(2.0); + float blinnPhong = exp2(A * NdotH - A); + float blinnNormalization = (m.SpecularPower + 8.0) / 8.0; + float normalDistribution = blinnPhong * blinnNormalization; + return fresnel * visibility * normalDistribution; } void DoDirectionalLightPS( @@ -336,10 +245,9 @@ void DoDirectionalLightPS( { vec3 L = normalize(-direction); float NdotL = max(dot(N, L), 0.0); - subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); color *= (1.0 - shadow) * NdotL; diffuse += color; - specular += color * SpecularGGX(m, N, V, L); + specular += color * SpecularBlinnPhong(m, N, V, L); } void DoPointLightPS( @@ -361,10 +269,9 @@ void DoPointLightPS( float att = clamp(1.0 - (dist / range), 0.0, 1.0); att *= att; float NdotL = max(dot(N, L), 0.0); - subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); color *= (1.0 - shadow) * NdotL * att; diffuse += color; - specular += color * SpecularGGX(m, N, V, L); + specular += color * SpecularBlinnPhong(m, N, V, L); } void DoSpotLightPS( @@ -390,10 +297,9 @@ void DoSpotLightPS( float theta = dot(L, normalize(-direction)); float epsilon = dcosInner - dcosOuter; float intensity = clamp((theta - dcosOuter) / epsilon, 0.0, 1.0); - subsurface += xCheapSubsurface(m.Subsurface, V, N, L, color); color *= (1.0 - shadow) * intensity * att; diffuse += color; - specular += color * SpecularGGX(m, N, V, L); + specular += color * SpecularBlinnPhong(m, N, V, L); } void Exposure() { @@ -549,7 +455,6 @@ Material UnpackMaterial( sampler2D texNormalW, float isMetallic, sampler2D texMaterial, - sampler2D texSubsurface, sampler2D texEmissive, mat3 TBN, vec2 uv) @@ -598,10 +503,6 @@ Material UnpackMaterial( m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); } - // Subsurface (color and intensity) - vec4 subsurface = texture2D(texSubsurface, uv); - m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); - // Emissive color m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); @@ -614,6 +515,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -713,19 +617,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -796,9 +713,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -813,7 +733,6 @@ void main() bbmod_NormalW, bbmod_IsMetallic, bbmod_Material, - bbmod_Subsurface, bbmod_Emissive, v_mTBN, v_vTexCoord); @@ -830,5 +749,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.vsh b/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.vsh index 814582af..c5c2bbbe 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.vsh @@ -36,7 +36,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -138,6 +138,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.yy b/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.yy index d2481929..b6c8a159 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.yy +++ b/BBMOD_GML/shaders/BBMOD_ShParticleLit/BBMOD_ShParticleLit.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShParticleLit", "parent": { - "name": "Particles", - "path": "folders/BBMOD/Particles.yy", + "name": "Shaders", + "path": "folders/BBMOD/Particles/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.fsh b/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.fsh index 2a3e408d..77a2627c 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.fsh @@ -110,6 +110,12 @@ uniform vec3 bbmod_LightDirectionalDir; // Color of the directional light uniform vec4 bbmod_LightDirectionalColor; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -163,6 +169,9 @@ void GammaCorrect() /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -274,7 +283,6 @@ Material UnpackMaterial( sampler2D texNormalW, float isMetallic, sampler2D texMaterial, - sampler2D texSubsurface, sampler2D texEmissive, mat3 TBN, vec2 uv) @@ -323,10 +331,6 @@ Material UnpackMaterial( m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); } - // Subsurface (color and intensity) - vec4 subsurface = texture2D(texSubsurface, uv); - m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); - // Emissive color m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); @@ -346,9 +350,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a *= softness; } Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -363,7 +371,6 @@ void main() bbmod_NormalW, bbmod_IsMetallic, bbmod_Material, - bbmod_Subsurface, bbmod_Emissive, v_mTBN, v_vTexCoord); @@ -380,5 +387,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.yy b/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.yy index 9dafbdb5..542d4f6d 100644 --- a/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.yy +++ b/BBMOD_GML/shaders/BBMOD_ShParticleUnlit/BBMOD_ShParticleUnlit.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShParticleUnlit", "parent": { - "name": "Particles", - "path": "folders/BBMOD/Particles.yy", + "name": "Shaders", + "path": "folders/BBMOD/Particles/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.fsh b/BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.fsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.fsh rename to BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.fsh diff --git a/BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.vsh b/BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.vsh new file mode 100644 index 00000000..6a6ea8ca --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.vsh @@ -0,0 +1,10 @@ +attribute vec4 in_Position; +attribute vec2 in_TextureCoord; + +varying vec2 v_vTexCoord; + +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + v_vTexCoord = in_TextureCoord; +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.yy b/BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.yy similarity index 80% rename from BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.yy rename to BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.yy index 554b485b..83e03aad 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShPrefilterDiffuse/__BBMOD_ShPrefilterDiffuse.yy +++ b/BBMOD_GML/shaders/BBMOD_ShPrefilterDiffuse/BBMOD_ShPrefilterDiffuse.yy @@ -1,7 +1,7 @@ { "resourceType": "GMShader", "resourceVersion": "1.0", - "name": "__BBMOD_ShPrefilterDiffuse", + "name": "BBMOD_ShPrefilterDiffuse", "parent": { "name": "Rendering", "path": "folders/BBMOD/Core/Rendering.yy", diff --git a/BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.fsh b/BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.fsh similarity index 100% rename from BBMOD_GML/shaders/__BBMOD_ShPrefilterSpecular/__BBMOD_ShPrefilterSpecular.fsh rename to BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.fsh diff --git a/BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.vsh b/BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.vsh new file mode 100644 index 00000000..6a6ea8ca --- /dev/null +++ b/BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.vsh @@ -0,0 +1,10 @@ +attribute vec4 in_Position; +attribute vec2 in_TextureCoord; + +varying vec2 v_vTexCoord; + +void main() +{ + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position; + v_vTexCoord = in_TextureCoord; +} diff --git a/BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.yy b/BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.yy similarity index 79% rename from BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.yy rename to BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.yy index 5fa8795c..2c83efa2 100644 --- a/BBMOD_GML/shaders/__BBMOD_ShCubemapToOctahedron/__BBMOD_ShCubemapToOctahedron.yy +++ b/BBMOD_GML/shaders/BBMOD_ShPrefilterSpecular/BBMOD_ShPrefilterSpecular.yy @@ -1,7 +1,7 @@ { "resourceType": "GMShader", "resourceVersion": "1.0", - "name": "__BBMOD_ShCubemapToOctahedron", + "name": "BBMOD_ShPrefilterSpecular", "parent": { "name": "Rendering", "path": "folders/BBMOD/Core/Rendering.yy", diff --git a/BBMOD_GML/shaders/BBMOD_ShSky/BBMOD_ShSky.fsh b/BBMOD_GML/shaders/BBMOD_ShSky/BBMOD_ShSky.fsh index 9732b6e2..5cfdce08 100644 --- a/BBMOD_GML/shaders/BBMOD_ShSky/BBMOD_ShSky.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShSky/BBMOD_ShSky.fsh @@ -3,6 +3,8 @@ varying vec3 v_vNormal; // Camera's exposure value uniform float bbmod_Exposure; +uniform float bbmod_HDR; + //#pragma include("EquirectangularMapping.xsh") #define X_PI 3.14159265359 #define X_2_PI 6.28318530718 @@ -73,7 +75,11 @@ float xLuminance(vec3 rgb) void main() { gl_FragColor.rgb = xGammaToLinear(xDecodeRGBM(texture2D(gm_BaseTexture, xVec3ToEquirectangularUv(v_vNormal)))); - gl_FragColor.rgb = vec3(1.0) - exp(-gl_FragColor.rgb * bbmod_Exposure); - gl_FragColor.rgb = xLinearToGamma(gl_FragColor.rgb); + if (bbmod_HDR == 0.0) + { + gl_FragColor.rgb *= bbmod_Exposure * bbmod_Exposure; + gl_FragColor.rgb = gl_FragColor.rgb / (vec3(1.0) + gl_FragColor.rgb); + gl_FragColor.rgb = xLinearToGamma(gl_FragColor.rgb); + } gl_FragColor.a = 1.0; } diff --git a/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.fsh b/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.fsh index 76ae9db6..00ddb179 100644 --- a/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.fsh @@ -103,37 +103,47 @@ uniform vec4 bbmod_LightPunctualDataA[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]; // [(isSpotLight, dcosInner, dcosOuter), (dX, dY, dZ), ...] uniform vec3 bbmod_LightPunctualDataB[2 * BBMOD_MAX_PUNCTUAL_LIGHTS]; +//////////////////////////////////////////////////////////////////////////////// +// Shadow mapping + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnablePS; +// Shadowmap texture +uniform sampler2D bbmod_Shadowmap; +// (1.0/shadowmapWidth, 1.0/shadowmapHeight) +uniform vec2 bbmod_ShadowmapTexel; +// The area that the shadowmap captures +uniform float bbmod_ShadowmapArea; +// The range over which meshes smoothly transition into shadow. +uniform float bbmod_ShadowmapBias; +// The index of the light that casts shadows. Use -1 for the directional light. +uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + //////////////////////////////////////////////////////////////////////////////// // Terrain +// First layer: // RGB: Base color, A: Opacity #define bbmod_TerrainBaseOpacity0 gm_BaseTexture // If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness0; // RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW0; -// Splatmap texture -uniform sampler2D bbmod_Splatmap; // Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex0; + +// Splatmap texture +uniform sampler2D bbmod_Splatmap; // Colormap texture uniform sampler2D bbmod_Colormap; //////////////////////////////////////////////////////////////////////////////// -// Shadow mapping +// HDR rendering -// 1.0 to enable shadows -uniform float bbmod_ShadowmapEnablePS; -// Shadowmap texture -uniform sampler2D bbmod_Shadowmap; -// (1.0/shadowmapWidth, 1.0/shadowmapHeight) -uniform vec2 bbmod_ShadowmapTexel; -// The area that the shadowmap captures -uniform float bbmod_ShadowmapArea; -// The range over which meshes smoothly transition into shadow. -uniform float bbmod_ShadowmapBias; -// The index of the light that casts shadows. Use -1 for the directional light. -uniform float bbmod_ShadowCasterIndex; +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -559,6 +569,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -658,19 +671,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -740,9 +766,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -778,5 +807,4 @@ void main() } PBRShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.vsh b/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.vsh index dd456f14..baf7c504 100644 --- a/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.vsh +++ b/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.vsh @@ -37,7 +37,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -115,6 +115,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.yy b/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.yy index 3e51e584..3ea42fb0 100644 --- a/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.yy +++ b/BBMOD_GML/shaders/BBMOD_ShTerrain/BBMOD_ShTerrain.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShTerrain", "parent": { - "name": "Terrain", - "path": "folders/BBMOD/Terrain.yy", + "name": "Shaders", + "path": "folders/BBMOD/Terrain/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.fsh b/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.fsh index 10f3021e..edf46f73 100644 --- a/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.fsh +++ b/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.fsh @@ -80,29 +80,47 @@ uniform vec4 bbmod_LightDirectionalColor; //////////////////////////////////////////////////////////////////////////////// // Terrain +// First layer: // RGB: Base color, A: Opacity #define bbmod_TerrainBaseOpacity0 gm_BaseTexture // If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness0; // RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW0; -// Splatmap texture -uniform sampler2D bbmod_Splatmap; // Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex0; + +// Splatmap texture +uniform sampler2D bbmod_Splatmap; // Colormap texture uniform sampler2D bbmod_Colormap; +// Second layer: +// RGB: Base color, A: Opacity uniform sampler2D bbmod_TerrainBaseOpacity1; +// If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness1; +// RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW1; +// Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex1; +// Third layer: +// RGB: Base color, A: Opacity uniform sampler2D bbmod_TerrainBaseOpacity2; +// If 1.0 then the material uses roughness uniform float bbmod_TerrainIsRoughness2; +// RGB: Tangent-space normal, A: Smoothness or roughness uniform sampler2D bbmod_TerrainNormalW2; +// Splatmap channel to read. Use -1 for none. uniform int bbmod_SplatmapIndex2; +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -261,9 +279,13 @@ void UnlitShader(Material material, float depth) gl_FragColor.a = material.Opacity; // Soft particles Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -319,8 +341,10 @@ void main() material.Base *= layerStrengthInv; material.Opacity *= layerStrengthInv; + material.Base += layerStrength * material1.Base; material.Opacity += layerStrength * material1.Opacity; + } if (bbmod_SplatmapIndex2 >= 0) @@ -334,8 +358,10 @@ void main() material.Base *= layerStrengthInv; material.Opacity *= layerStrengthInv; + material.Base += layerStrength * material2.Base; material.Opacity += layerStrength * material2.Opacity; + } // Colormap @@ -347,5 +373,4 @@ void main() } UnlitShader(material, v_vPosition.z); - } diff --git a/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.yy b/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.yy index 30001dff..20c6e9dd 100644 --- a/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.yy +++ b/BBMOD_GML/shaders/BBMOD_ShTerrainUnlit/BBMOD_ShTerrainUnlit.yy @@ -3,8 +3,8 @@ "resourceVersion": "1.0", "name": "BBMOD_ShTerrainUnlit", "parent": { - "name": "Terrain", - "path": "folders/BBMOD/Terrain.yy", + "name": "Shaders", + "path": "folders/BBMOD/Terrain/Shaders.yy", }, "type": 1, } \ No newline at end of file diff --git a/BBMOD_GML/shaders/ShZombie/ShZombie.fsh b/BBMOD_GML/shaders/ShZombie/ShZombie.fsh index 21f3e2a5..a3d804b8 100644 --- a/BBMOD_GML/shaders/ShZombie/ShZombie.fsh +++ b/BBMOD_GML/shaders/ShZombie/ShZombie.fsh @@ -170,6 +170,14 @@ uniform float bbmod_ShadowmapArea; uniform float bbmod_ShadowmapBias; // The index of the light that casts shadows. Use -1 for the directional light. uniform float bbmod_ShadowCasterIndex; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetPS; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; //////////////////////////////////////////////////////////////////////////////// // @@ -633,6 +641,9 @@ Material UnpackMaterial( /// @return Point projected to view-space. vec3 xProject(vec2 tanAspect, vec2 texCoord, float depth) { +#if !(defined(_YY_HLSL11_) || defined(_YY_PSSL_)) + tanAspect.y *= -1.0; +#endif return vec3(tanAspect * (texCoord * 2.0 - 1.0) * depth, depth); } @@ -732,19 +743,32 @@ void PBRShader(Material material, float depth) float shadow = 0.0; if (bbmod_ShadowmapEnablePS == 1.0) { - vec4 shadowmapPos = v_vPosShadowmap; - shadowmapPos.xy /= shadowmapPos.w; - float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) - ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) - : 1.0; - shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; - #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) - shadowmapPos.y = 1.0 - shadowmapPos.y; - #endif - shadowmapPos.z /= bbmod_ShadowmapArea; - - shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) - * shadowmapAtt; + int shadowCasterIndex = int(bbmod_ShadowCasterIndex); + bool isPoint = (shadowCasterIndex >= 0) && (bbmod_LightPunctualDataB[shadowCasterIndex * 2].x == 0.0); + + if (!isPoint) + { + vec4 shadowmapPos = v_vPosShadowmap; + shadowmapPos.xy /= shadowmapPos.w; + float shadowmapAtt = (bbmod_ShadowCasterIndex == -1.0) + ? clamp((1.0 - length(shadowmapPos.xy)) / 0.1, 0.0, 1.0) + : 1.0; + shadowmapPos.xy = shadowmapPos.xy * 0.5 + 0.5; + #if defined(_YY_HLSL11_) || defined(_YY_PSSL_) + shadowmapPos.y = 1.0 - shadowmapPos.y; + #endif + shadowmapPos.z /= bbmod_ShadowmapArea; + + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, shadowmapPos.xy, shadowmapPos.z) + * shadowmapAtt; + } + else + { + vec3 position = bbmod_LightPunctualDataA[shadowCasterIndex * 2].xyz; + vec3 lightVec = position - v_vVertex; + vec2 uv = xVec3ToOctahedronUv(-lightVec); + shadow = ShadowMap(bbmod_Shadowmap, bbmod_ShadowmapTexel, uv, (length(lightVec) - bbmod_ShadowmapNormalOffsetPS) / bbmod_ShadowmapArea); + } } // IBL @@ -814,9 +838,12 @@ void PBRShader(Material material, float depth) // Fog Fog(depth); - Exposure(); - TonemapReinhard(); - GammaCorrect(); + if (bbmod_HDR == 0.0) + { + Exposure(); + TonemapReinhard(); + GammaCorrect(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -845,6 +872,13 @@ void main() { discard; } + material.Emissive = mix( + material.Emissive, + xGammaToLinear(u_vDissolveColor), + (1.0 - clamp((noise - u_fDissolveThreshold) / u_fDissolveRange, 0.0, 1.0)) * u_fDissolveThreshold); + + // Silhouette + material.Emissive = mix(material.Emissive, xGammaToLinear(u_vSilhouette.rgb), u_vSilhouette.a); if (material.Opacity < bbmod_AlphaTest) { @@ -852,13 +886,4 @@ void main() } PBRShader(material, v_vPosition.z); - - // Dissolve - gl_FragColor.rgb = mix( - gl_FragColor.rgb, - u_vDissolveColor, - (1.0 - clamp((noise - u_fDissolveThreshold) / u_fDissolveRange, 0.0, 1.0)) * u_fDissolveThreshold); - // Silhouette - gl_FragColor.rgb = mix(gl_FragColor.rgb, u_vSilhouette.rgb, u_vSilhouette.a); - } diff --git a/BBMOD_GML/shaders/ShZombie/ShZombie.vsh b/BBMOD_GML/shaders/ShZombie/ShZombie.vsh index d502dc61..fd6dc266 100644 --- a/BBMOD_GML/shaders/ShZombie/ShZombie.vsh +++ b/BBMOD_GML/shaders/ShZombie/ShZombie.vsh @@ -41,7 +41,7 @@ uniform float bbmod_ShadowmapEnableVS; // WORLD_VIEW_PROJECTION matrix used when rendering shadowmap uniform mat4 bbmod_ShadowmapMatrix; // Offsets vertex position by its normal scaled by this value -uniform float bbmod_ShadowmapNormalOffset; +uniform float bbmod_ShadowmapNormalOffsetVS; //////////////////////////////////////////////////////////////////////////////// // @@ -166,6 +166,6 @@ void main() if (bbmod_ShadowmapEnableVS == 1.0) { v_vPosShadowmap = bbmod_ShadowmapMatrix - * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffset, 1.0); + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); } } diff --git a/BBMOD_GML/shaders/ShZombieDepth/ShZombieDepth.fsh b/BBMOD_GML/shaders/ShZombieDepth/ShZombieDepth.fsh index 87f1461b..cba5df1c 100644 --- a/BBMOD_GML/shaders/ShZombieDepth/ShZombieDepth.fsh +++ b/BBMOD_GML/shaders/ShZombieDepth/ShZombieDepth.fsh @@ -77,6 +77,18 @@ uniform float bbmod_ZFar; // Camera's exposure value uniform float bbmod_Exposure; +//////////////////////////////////////////////////////////////////////////////// +// Writing shadow maps + +// 0.0 = output depth, 1.0 = output distance from camera +uniform float u_fOutputDistance; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + //////////////////////////////////////////////////////////////////////////////// // // Includes @@ -134,6 +146,6 @@ void main() discard; } - DepthShader(v_vPosition.z); + DepthShader((u_fOutputDistance == 1.0) ? length(v_vPosition.xyz) : v_vPosition.z); } diff --git a/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.fsh b/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.fsh new file mode 100644 index 00000000..2872a582 --- /dev/null +++ b/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.fsh @@ -0,0 +1,354 @@ +// FIXME: Temporary fix! +precision highp float; + +// Dissolve effect +uniform vec3 u_vDissolveColor; +uniform float u_fDissolveThreshold; +uniform float u_fDissolveRange; +uniform vec2 u_vDissolveScale; + +// Silhouette effect +uniform vec4 u_vSilhouette; + +float Random(in vec2 st) +{ + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +// Based on Morgan McGuire @morgan3d +// https://www.shadertoy.com/view/4dS3Wd +float Noise(in vec2 st) +{ + vec2 i = floor(st); + vec2 f = fract(st); + float a = Random(i); + float b = Random(i + vec2(1.0, 0.0)); + float c = Random(i + vec2(0.0, 1.0)); + float d = Random(i + vec2(1.0, 1.0)); + vec2 u = smoothstep(0.0, 1.0, f); + return mix( + mix(a, b, u.x), + mix(c, d, u.x), + u.y); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of punctual lights +#define BBMOD_MAX_PUNCTUAL_LIGHTS 8 +// Number of samples used when computing shadows +#define SHADOWMAP_SAMPLE_COUNT 12 + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// + +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +//////////////////////////////////////////////////////////////////////////////// +// Material + +// Material index +// uniform float bbmod_MaterialIndex; + +// RGB: Base color, A: Opacity +#define bbmod_BaseOpacity gm_BaseTexture + +// RGBA +uniform vec4 bbmod_BaseOpacityMultiplier; + +// If 1.0 then the material uses roughness +uniform float bbmod_IsRoughness; +// RGB: Tangent-space normal, A: Smoothness or roughness +uniform sampler2D bbmod_NormalW; +// If 1.0 then the material uses metallic workflow +uniform float bbmod_IsMetallic; +// RGB: specular color / R: Metallic, G: ambient occlusion +uniform sampler2D bbmod_Material; + +// RGB: Subsurface color, A: Intensity +uniform sampler2D bbmod_Subsurface; +// RGBA: RGBM encoded emissive color +uniform sampler2D bbmod_Emissive; + +// Pixels with alpha less than this value will be discarded +uniform float bbmod_AlphaTest; + +//////////////////////////////////////////////////////////////////////////////// +// Camera + +// Camera's position in world space +uniform vec3 bbmod_CamPos; +// Distance to the far clipping plane +uniform float bbmod_ZFar; +// Camera's exposure value +uniform float bbmod_Exposure; + +//////////////////////////////////////////////////////////////////////////////// +// G-Buffer + +// Lookup texture for best fit normal encoding +uniform sampler2D u_texBestFitNormalLUT; + +//////////////////////////////////////////////////////////////////////////////// +// HDR rendering + +// 0.0 = apply exposure, tonemap and gamma correct, 1.0 = output raw values +uniform float bbmod_HDR; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +/// @param d Linearized depth to encode. +/// @return Encoded depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +vec3 xEncodeDepth(float d) +{ + const float inv255 = 1.0 / 255.0; + vec3 enc; + enc.x = d; + enc.y = d * 255.0; + enc.z = enc.y * 255.0; + enc = fract(enc); + float temp = enc.z * inv255; + enc.x -= enc.y * inv255; + enc.y -= temp; + enc.z -= temp; + return enc; +} + +/// @param c Encoded depth. +/// @return Docoded linear depth. +/// @source http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ +float xDecodeDepth(vec3 c) +{ + const float inv255 = 1.0 / 255.0; + return c.x + (c.y * inv255) + (c.z * inv255 * inv255); +} +/// @source http://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf +vec3 xBestFitNormal(vec3 normal, sampler2D tex) +{ + normal = normalize(normal); + vec3 normalUns = abs(normal); + float maxNAbs = max(max(normalUns.x, normalUns.y), normalUns.z); + vec2 texCoord = normalUns.z < maxNAbs ? (normalUns.y < maxNAbs ? normalUns.yz : normalUns.xz) : normalUns.xy; + texCoord = texCoord.x < texCoord.y ? texCoord.yx : texCoord.xy; + texCoord.y /= texCoord.x; + normal /= maxNAbs; + float fittingScale = texture2D(tex, texCoord).r; + return normal * fittingScale; +} +struct Material +{ + vec3 Base; + float Opacity; + vec3 Normal; + float Metallic; + float Roughness; + vec3 Specular; + float Smoothness; + float SpecularPower; + float AO; + vec3 Emissive; + vec4 Subsurface; + vec3 Lightmap; +}; + +Material CreateMaterial() +{ + Material m; + m.Base = vec3(1.0); + m.Opacity = 1.0; + m.Normal = vec3(0.0, 0.0, 1.0); + m.Metallic = 0.0; + m.Roughness = 1.0; + m.Specular = vec3(0.0); + m.Smoothness = 0.0; + m.SpecularPower = 1.0; + m.AO = 1.0; + m.Emissive = vec3(0.0); + m.Subsurface = vec4(0.0); + m.Lightmap = vec3(0.0); + return m; +} +#define F0_DEFAULT vec3(0.04) +#define X_GAMMA 2.2 + +/// @desc Converts gamma space color to linear space. +vec3 xGammaToLinear(vec3 rgb) +{ + return pow(rgb, vec3(X_GAMMA)); +} + +/// @desc Converts linear space color to gamma space. +vec3 xLinearToGamma(vec3 rgb) +{ + return pow(rgb, vec3(1.0 / X_GAMMA)); +} + +/// @desc Gets color's luminance. +float xLuminance(vec3 rgb) +{ + return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b); +} +/// @note Input color should be in gamma space. +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec4 xEncodeRGBM(vec3 color) +{ + vec4 rgbm; + color *= 1.0 / 6.0; + rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 0.000001)), 0.0, 1.0); + rgbm.a = ceil(rgbm.a * 255.0) / 255.0; + rgbm.rgb = color / rgbm.a; + return rgbm; +} + +/// @source https://graphicrants.blogspot.cz/2009/04/rgbm-color-encoding.html +vec3 xDecodeRGBM(vec4 rgbm) +{ + return 6.0 * rgbm.rgb * rgbm.a; +} + +/// @desc Unpacks material from textures. +/// @param texBaseOpacity RGB: base color, A: opacity +/// @param isRoughness +/// @param texNormalW +/// @param isMetallic +/// @param texMaterial +/// @param texSubsurface RGB: subsurface color, A: intensity +/// @param texEmissive RGBA: RGBM encoded emissive color +/// @param texLightmap RGBA: RGBM encoded lightmap +/// @param uvLightmap Lightmap texture coordinates +/// @param TBN Tangent-bitangent-normal matrix +/// @param uv Texture coordinates +Material UnpackMaterial( + sampler2D texBaseOpacity, + float isRoughness, + sampler2D texNormalW, + float isMetallic, + sampler2D texMaterial, + sampler2D texSubsurface, + sampler2D texEmissive, + mat3 TBN, + vec2 uv) +{ + Material m = CreateMaterial(); + + // Base color and opacity + vec4 baseOpacity = texture2D(texBaseOpacity, + uv + ); + m.Base = xGammaToLinear(baseOpacity.rgb); + m.Opacity = baseOpacity.a; + + // Normal vector and smoothness/roughness + vec4 normalW = texture2D(texNormalW, + uv + ); + m.Normal = normalize(TBN * (normalW.rgb * 2.0 - 1.0)); + + if (isRoughness == 1.0) + { + m.Roughness = mix(0.1, 0.9, normalW.a); + m.Smoothness = 1.0 - m.Roughness; + } + else + { + m.Smoothness = mix(0.1, 0.9, normalW.a); + m.Roughness = 1.0 - m.Smoothness; + } + + // Material properties + vec4 materialProps = texture2D(texMaterial, + uv + ); + + if (isMetallic == 1.0) + { + m.Metallic = materialProps.r; + m.AO = materialProps.g; + m.Specular = mix(F0_DEFAULT, m.Base, m.Metallic); + m.Base *= (1.0 - m.Metallic); + } + else + { + m.Specular = materialProps.rgb; + m.SpecularPower = exp2(1.0 + (m.Smoothness * 10.0)); + } + + // Subsurface (color and intensity) + vec4 subsurface = texture2D(texSubsurface, uv); + m.Subsurface = vec4(xGammaToLinear(subsurface.rgb).rgb, subsurface.a); + + // Emissive color + m.Emissive = xGammaToLinear(xDecodeRGBM(texture2D(texEmissive, uv))); + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + Material material = UnpackMaterial( + bbmod_BaseOpacity, + bbmod_IsRoughness, + bbmod_NormalW, + bbmod_IsMetallic, + bbmod_Material, + bbmod_Subsurface, + bbmod_Emissive, + v_mTBN, + v_vTexCoord); + + material.Base *= xGammaToLinear(bbmod_BaseOpacityMultiplier.rgb); + material.Opacity *= bbmod_BaseOpacityMultiplier.a; + + // Dissolve + float noise = Noise(v_vTexCoord * u_vDissolveScale); + if (noise < u_fDissolveThreshold) + { + discard; + } + material.Emissive = mix( + material.Emissive, + xGammaToLinear(u_vDissolveColor), + (1.0 - clamp((noise - u_fDissolveThreshold) / u_fDissolveRange, 0.0, 1.0)) * u_fDissolveThreshold); + + // Silhouette + material.Emissive = mix(material.Emissive, xGammaToLinear(u_vSilhouette.rgb), u_vSilhouette.a); + + if (material.Opacity < bbmod_AlphaTest) + { + discard; + } + + gl_FragData[0] = vec4(xLinearToGamma(mix(material.Base, material.Specular, material.Metallic)), material.AO); + gl_FragData[1] = vec4(xBestFitNormal(material.Normal, u_texBestFitNormalLUT) * 0.5 + 0.5, material.Roughness); + gl_FragData[2] = vec4(xEncodeDepth(v_vPosition.z / bbmod_ZFar), material.Metallic); + gl_FragData[3] = vec4(material.Emissive, 1.0); + if (bbmod_HDR == 0.0) + { + gl_FragData[3].rgb = xLinearToGamma(gl_FragData[3].rgb); + } +} diff --git a/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.vsh b/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.vsh new file mode 100644 index 00000000..1e286fba --- /dev/null +++ b/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.vsh @@ -0,0 +1,171 @@ +// FIXME: Temporary fix! +precision highp float; + +//////////////////////////////////////////////////////////////////////////////// +// +// Defines +// + +// Maximum number of bones of animated models +#define BBMOD_MAX_BONES 128 +// Maximum number of vec4 uniforms for dynamic batch data +#define BBMOD_MAX_BATCH_VEC4S 192 + +//////////////////////////////////////////////////////////////////////////////// +// +// Attributes +// +attribute vec4 in_Position; + +attribute vec3 in_Normal; + +attribute vec2 in_TextureCoord0; + +attribute vec4 in_TangentW; + +attribute vec4 in_BoneIndex; +attribute vec4 in_BoneWeight; + +//////////////////////////////////////////////////////////////////////////////// +// +// Uniforms +// + +uniform vec2 bbmod_TextureOffset; +uniform vec2 bbmod_TextureScale; + +uniform vec4 bbmod_Bones[2 * BBMOD_MAX_BONES]; + +// 1.0 to enable shadows +uniform float bbmod_ShadowmapEnableVS; +// WORLD_VIEW_PROJECTION matrix used when rendering shadowmap +uniform mat4 bbmod_ShadowmapMatrix; +// Offsets vertex position by its normal scaled by this value +uniform float bbmod_ShadowmapNormalOffsetVS; + +//////////////////////////////////////////////////////////////////////////////// +// +// Varyings +// +varying vec3 v_vVertex; + +varying vec2 v_vTexCoord; +varying mat3 v_mTBN; +varying vec4 v_vPosition; + +varying vec4 v_vPosShadowmap; + +varying vec4 v_vEye; + +//////////////////////////////////////////////////////////////////////////////// +// +// Includes +// +vec3 QuaternionRotate(vec4 q, vec3 v) +{ + return (v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v)); +} + +vec3 DualQuaternionTransform(vec4 real, vec4 dual, vec3 v) +{ + return (QuaternionRotate(real, v) + + 2.0 * (real.w * dual.xyz - dual.w * real.xyz + cross(real.xyz, dual.xyz))); +} + +/// @desc Transforms vertex and normal by animation and/or batch data. +/// +/// @param vertex Variable to hold the transformed vertex. +/// @param normal Variable to hold the transformed normal. +/// @param tangent Variable to hold the transformed tangent. +/// @param bitangent Variable to hold the transformed bitangent. +void Transform( + inout vec4 vertex, + inout vec3 normal, + inout vec3 tangent, + inout vec3 bitangent) +{ + + // Source: + // https://www.cs.utah.edu/~ladislav/kavan07skinning/kavan07skinning.pdf + // https://www.cs.utah.edu/~ladislav/dq/dqs.cg + ivec4 i = ivec4(in_BoneIndex) * 2; + ivec4 j = i + 1; + + vec4 real0 = bbmod_Bones[i.x]; + vec4 real1 = bbmod_Bones[i.y]; + vec4 real2 = bbmod_Bones[i.z]; + vec4 real3 = bbmod_Bones[i.w]; + + vec4 dual0 = bbmod_Bones[j.x]; + vec4 dual1 = bbmod_Bones[j.y]; + vec4 dual2 = bbmod_Bones[j.z]; + vec4 dual3 = bbmod_Bones[j.w]; + + if (dot(real0, real1) < 0.0) { real1 *= -1.0; dual1 *= -1.0; } + if (dot(real0, real2) < 0.0) { real2 *= -1.0; dual2 *= -1.0; } + if (dot(real0, real3) < 0.0) { real3 *= -1.0; dual3 *= -1.0; } + + vec4 blendReal = + real0 * in_BoneWeight.x + + real1 * in_BoneWeight.y + + real2 * in_BoneWeight.z + + real3 * in_BoneWeight.w; + + vec4 blendDual = + dual0 * in_BoneWeight.x + + dual1 * in_BoneWeight.y + + dual2 * in_BoneWeight.z + + dual3 * in_BoneWeight.w; + + float len = length(blendReal); + blendReal /= len; + blendDual /= len; + + vertex = vec4(DualQuaternionTransform(blendReal, blendDual, vertex.xyz), 1.0); + normal = QuaternionRotate(blendReal, normal); + tangent = QuaternionRotate(blendReal, tangent); + bitangent = QuaternionRotate(blendReal, bitangent); + + vertex = gm_Matrices[MATRIX_WORLD] * vertex; + normal = normalize((gm_Matrices[MATRIX_WORLD] * vec4(normal, 0.0)).xyz); + tangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(tangent, 0.0)).xyz); + bitangent = normalize((gm_Matrices[MATRIX_WORLD] * vec4(bitangent, 0.0)).xyz); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// +void main() +{ + vec4 position = in_Position; + vec3 normal = in_Normal; + vec3 tangent = in_TangentW.xyz; + vec3 bitangent = cross(normal, tangent) * in_TangentW.w; + + Transform(position, normal, tangent, bitangent); + + vec4 positionWVP = gm_Matrices[MATRIX_PROJECTION] * (gm_Matrices[MATRIX_VIEW] * position); + v_vVertex = position.xyz; + + gl_Position = positionWVP; + v_vPosition = positionWVP; + v_vTexCoord = bbmod_TextureOffset + in_TextureCoord0 * bbmod_TextureScale; + + v_vEye.xyz = normalize(-vec3( + gm_Matrices[MATRIX_VIEW][0][2], + gm_Matrices[MATRIX_VIEW][1][2], + gm_Matrices[MATRIX_VIEW][2][2] + )); + v_vEye.w = (gm_Matrices[MATRIX_PROJECTION][2][3] == 0.0) ? 1.0 : 0.0; + + v_mTBN = mat3(tangent, bitangent, normal); + + //////////////////////////////////////////////////////////////////////////// + // Vertex position in shadowmap + if (bbmod_ShadowmapEnableVS == 1.0) + { + v_vPosShadowmap = bbmod_ShadowmapMatrix + * vec4(v_vVertex + normal * bbmod_ShadowmapNormalOffsetVS, 1.0); + } +} diff --git a/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.yy b/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.yy new file mode 100644 index 00000000..de591c5e --- /dev/null +++ b/BBMOD_GML/shaders/ShZombieGBuffer/ShZombieGBuffer.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "ShZombieGBuffer", + "parent": { + "name": "Shaders", + "path": "folders/Demo/Shaders.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/5e52c852-96b0-44bd-a39b-919074af4aec.png b/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/5e52c852-96b0-44bd-a39b-919074af4aec.png new file mode 100644 index 00000000..a54c0f60 Binary files /dev/null and b/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/5e52c852-96b0-44bd-a39b-919074af4aec.png differ diff --git a/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/BBMOD_SprBestFitNormalLUT.yy b/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/BBMOD_SprBestFitNormalLUT.yy new file mode 100644 index 00000000..ee6dbaac --- /dev/null +++ b/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/BBMOD_SprBestFitNormalLUT.yy @@ -0,0 +1,74 @@ +{ + "resourceType": "GMSprite", + "resourceVersion": "1.0", + "name": "BBMOD_SprBestFitNormalLUT", + "bbox_bottom": 1023, + "bbox_left": 0, + "bbox_right": 1023, + "bbox_top": 0, + "bboxMode": 0, + "collisionKind": 1, + "collisionTolerance": 0, + "DynamicTexturePage": false, + "edgeFiltering": false, + "For3D": true, + "frames": [ + {"resourceType":"GMSpriteFrame","resourceVersion":"1.1","name":"5e52c852-96b0-44bd-a39b-919074af4aec",}, + ], + "gridX": 0, + "gridY": 0, + "height": 1024, + "HTile": false, + "layers": [ + {"resourceType":"GMImageLayer","resourceVersion":"1.0","name":"0bfbc505-03d0-43b7-82d8-d8a257f154e1","blendMode":0,"displayName":"default","isLocked":false,"opacity":100.0,"visible":true,}, + ], + "nineSlice": null, + "origin": 0, + "parent": { + "name": "Sprites", + "path": "folders/BBMOD/DeferredRenderer/Sprites.yy", + }, + "preMultiplyAlpha": false, + "sequence": { + "resourceType": "GMSequence", + "resourceVersion": "1.4", + "name": "BBMOD_SprBestFitNormalLUT", + "autoRecord": true, + "backdropHeight": 768, + "backdropImageOpacity": 0.5, + "backdropImagePath": "", + "backdropWidth": 1366, + "backdropXOffset": 0.0, + "backdropYOffset": 0.0, + "events": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "eventStubScript": null, + "eventToFunction": {}, + "length": 1.0, + "lockOrigin": false, + "moments": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "playback": 1, + "playbackSpeed": 30.0, + "playbackSpeedType": 0, + "showBackdrop": true, + "showBackdropImage": false, + "timeUnits": 1, + "tracks": [ + {"resourceType":"GMSpriteFramesTrack","resourceVersion":"1.0","name":"frames","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[ + {"resourceType":"Keyframe","resourceVersion":"1.0","Channels":{"0":{"resourceType":"SpriteFrameKeyframe","resourceVersion":"1.0","Id":{"name":"5e52c852-96b0-44bd-a39b-919074af4aec","path":"sprites/BBMOD_SprBestFitNormalLUT/BBMOD_SprBestFitNormalLUT.yy",},},},"Disabled":false,"id":"6b55ada3-89ab-4c27-8339-4fddaed912e1","IsCreationKey":false,"Key":0.0,"Length":1.0,"Stretch":false,}, + ],},"modifiers":[],"spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange": null, + "volume": 1.0, + "xorigin": 0, + "yorigin": 0, + }, + "swatchColours": null, + "swfPrecision": 2.525, + "textureGroupId": { + "name": "Default", + "path": "texturegroups/Default", + }, + "type": 0, + "VTile": false, + "width": 1024, +} \ No newline at end of file diff --git a/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/layers/5e52c852-96b0-44bd-a39b-919074af4aec/0bfbc505-03d0-43b7-82d8-d8a257f154e1.png b/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/layers/5e52c852-96b0-44bd-a39b-919074af4aec/0bfbc505-03d0-43b7-82d8-d8a257f154e1.png new file mode 100644 index 00000000..a54c0f60 Binary files /dev/null and b/BBMOD_GML/sprites/BBMOD_SprBestFitNormalLUT/layers/5e52c852-96b0-44bd-a39b-919074af4aec/0bfbc505-03d0-43b7-82d8-d8a257f154e1.png differ diff --git a/BBMOD_GML/sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy b/BBMOD_GML/sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy index 586712e8..4938b800 100644 --- a/BBMOD_GML/sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy +++ b/BBMOD_GML/sprites/BBMOD_SprCheckerboard/BBMOD_SprCheckerboard.yy @@ -25,8 +25,8 @@ "nineSlice": null, "origin": 0, "parent": { - "name": "Core", - "path": "folders/BBMOD/Core.yy", + "name": "Sprites", + "path": "folders/BBMOD/Core/Sprites.yy", }, "preMultiplyAlpha": false, "sequence": { diff --git a/BBMOD_GML/sprites/BBMOD_SprGizmo/BBMOD_SprGizmo.yy b/BBMOD_GML/sprites/BBMOD_SprGizmo/BBMOD_SprGizmo.yy index 0c8a7a30..b18c1a81 100644 --- a/BBMOD_GML/sprites/BBMOD_SprGizmo/BBMOD_SprGizmo.yy +++ b/BBMOD_GML/sprites/BBMOD_SprGizmo/BBMOD_SprGizmo.yy @@ -26,8 +26,8 @@ "nineSlice": null, "origin": 0, "parent": { - "name": "Gizmo", - "path": "folders/BBMOD/Gizmo.yy", + "name": "Sprites", + "path": "folders/BBMOD/Gizmo/Sprites.yy", }, "preMultiplyAlpha": false, "sequence": { diff --git a/BBMOD_GML/sprites/BBMOD_SprParticle/BBMOD_SprParticle.yy b/BBMOD_GML/sprites/BBMOD_SprParticle/BBMOD_SprParticle.yy index 4e4caca7..60bfa2d4 100644 --- a/BBMOD_GML/sprites/BBMOD_SprParticle/BBMOD_SprParticle.yy +++ b/BBMOD_GML/sprites/BBMOD_SprParticle/BBMOD_SprParticle.yy @@ -25,8 +25,8 @@ "nineSlice": null, "origin": 0, "parent": { - "name": "Particles", - "path": "folders/BBMOD/Particles.yy", + "name": "Sprites", + "path": "folders/BBMOD/Particles/Sprites.yy", }, "preMultiplyAlpha": false, "sequence": { diff --git a/BBMOD_GML/sprites/bbmod_sprblack/bbmod_sprblack.yy b/BBMOD_GML/sprites/bbmod_sprblack/bbmod_sprblack.yy index e88aa73e..eb7336f3 100644 --- a/BBMOD_GML/sprites/bbmod_sprblack/bbmod_sprblack.yy +++ b/BBMOD_GML/sprites/bbmod_sprblack/bbmod_sprblack.yy @@ -25,8 +25,8 @@ "nineSlice": null, "origin": 0, "parent": { - "name": "Core", - "path": "folders/BBMOD/Core.yy", + "name": "Sprites", + "path": "folders/BBMOD/Core/Sprites.yy", }, "preMultiplyAlpha": false, "sequence": { diff --git a/BBMOD_GML/sprites/bbmod_sprwhite/bbmod_sprwhite.yy b/BBMOD_GML/sprites/bbmod_sprwhite/bbmod_sprwhite.yy index 4ae2d903..05b452b1 100644 --- a/BBMOD_GML/sprites/bbmod_sprwhite/bbmod_sprwhite.yy +++ b/BBMOD_GML/sprites/bbmod_sprwhite/bbmod_sprwhite.yy @@ -25,8 +25,8 @@ "nineSlice": null, "origin": 0, "parent": { - "name": "Core", - "path": "folders/BBMOD/Core.yy", + "name": "Sprites", + "path": "folders/BBMOD/Core/Sprites.yy", }, "preMultiplyAlpha": false, "sequence": { diff --git a/docs_src/Changelog/Changelog3.20.0.md b/docs_src/Changelog/Changelog3.20.0.md new file mode 100644 index 00000000..fef6ad64 --- /dev/null +++ b/docs_src/Changelog/Changelog3.20.0.md @@ -0,0 +1,78 @@ +# Changelog 3.20.0 +This release brings a new deferred rendering pipeline with support for unlimited number of shadow-casting lights. All light types, including point lights, can now cast shadows. Please note that the deferred renderer has specific hardware requirements and therefore it is not supported on all platforms! When deferred rendering is not available, you can still use the old default renderer, but that is still limited to maximum 8 punctual lights and only a single shadow-casting light. Additionally, you can now configure frame skip for capturing shadowmaps or mark a light as "static" to capture its shadowmap only once to increase performance. + +* Added new struct `BBMOD_DeferredRenderer`, which is a deferred renderer with support for unlimited number of shadow-casting lights. +* Added new function `bbmod_deferred_renderer_is_supported`, which checks whether deferred renderer is supported on the current platform. +* Added new macro `BBMOD_SHADER_GBUFFER`, which is a shader for rendering models into the G-buffer. +* Added new macro `BBMOD_MATERIAL_DEFERRED`, which is an opaque material that can be used with the new `BBMOD_DeferredRenderer`. +* Added new macro `BBMOD_SHADER_TERRAIN_GBUFFER`, which is a shader for rendering terrain into the G-buffer. Supports 3 terrain layers at most! +* Added new macro `BBMOD_MATERIAL_TERRAIN_DEFERRED`, which is a terrain material that can be used with the new `BBMOD_DeferredRenderer`. +* Moved properties `EnableSSAO`, `SSAOScale`, `SSAORadius`, `SSAOPower`, `SSAOAngleBias`, `SSAODepthRange`, `SSAOSelfOcclusionBias` and `SSAOBlurDepthRange` from `BBMOD_DefaultRenderer` to `BBMOD_BaseRenderer`. +* `BBMOD_PointLight` can now also cast shadows. +* Added new property `Frameskip` to `BBMOD_Light`, which is the number of frames to skip between individual updates of the light's shadowmap. +* Added new property `Static` to `BBMOD_Light`, which when set to `true`, the light's shadowmap is captured only once. +* Added new property `NeedsUpdate` to `BBMOD_Light`, which if `true`, then the light's shadowmap needs to be updated. +* Added new member `Background` to enum `BBMOD_ERenderPass`, which is a render pass for background objects (e.g. skydome). +* Material `BBMOD_MATERIAL_SKY` now uses the `Background` render pass instead of `Forward`. +* Implemented the new `Background` render pass into `BBMOD_DefaultRenderer`. +* Added new macro `BBMOD_U_SHADOWMAP_NORMAL_OFFSET_VS`, which is the name of a vertex shader uniform of type `float` that holds how much are vertices offset by their normal before they are transformed into shadowmap-space, using formula `vertex + normal * normalOffset`. +* Added new macro `BBMOD_U_SHADOWMAP_NORMAL_OFFSET_PS`, which is the name of a fragment shader uniform of type `float` that holds how much are vertices offset by their normal before they are transformed into shadowmap-space, using formula `vertex + normal * normalOffset`. +* Macro `BBMOD_U_SHADOWMAP_NORMAL_OFFSET` is now **obsolete**! Please use the new `BBMOD_U_SHADOWMAP_NORMAL_OFFSET_VS` instead. +* Added new function `bbmod_hdr_is_supported`, which checks whether high dynamic range (HDR) rendering is supported on the current platform. +* Added new macro `BBMOD_U_HDR`, which is the name of a fragment shader uniform of type `float` that holds whether HDR rendering is enabled (1.0) or not (0.0). +* Added new function `bbmod_shader_set_normal_matrix`, which sets the `BBMOD_U_NORMAL_MATRIX` uniform. +* Added new function `bbmod_shader_set_texture_offset`, which sets the `BBMOD_U_TEXTURE_OFFSET` uniform. +* Added new function `bbmod_shader_set_texture_scale`, which sets the `BBMOD_U_TEXTURE_SCALE` uniform. +* Added new function `bbmod_shader_set_bones`, which sets the `BBMOD_U_BONES` uniform. +* Added new function `bbmod_shader_set_batch_data`, which sets the `BBMOD_U_BATCH_DATA` uniform. +* Added new function `bbmod_shader_set_instance_id`, which sets the `BBMOD_U_INSTANCE_ID` uniform. +* Added new function `bbmod_shader_set_material_index`, which sets the `BBMOD_U_MATERIAL_INDEX` uniform. +* Added new function `bbmod_shader_set_base_opacity_multiplier`, which sets the `BBMOD_U_BASE_OPACITY_MULTIPLIER` uniform. +* Added new function `bbmod_shader_set_normal_smoothness`, which sets uniforms `BBMOD_U_NORMAL_W` and `BBMOD_U_IS_ROUGHNESS`. +* Added new function `bbmod_shader_set_normal_roughness`, which sets uniforms `BBMOD_U_NORMAL_W` and `BBMOD_U_IS_ROUGHNESS`. +* Added new function `bbmod_shader_set_specular_color`, which sets uniforms `BBMOD_U_MATERIAL` and `BBMOD_U_IS_METALLIC`. +* Added new function `bbmod_shader_set_metallic_ao`, which sets uniforms `BBMOD_U_MATERIAL` and `BBMOD_U_IS_METALLIC`. +* Added new function `bbmod_shader_set_subsurface`, which sets the `BBMOD_U_SUBSURFACE` uniform. +* Added new function `bbmod_shader_set_emissive`, which sets the `BBMOD_U_EMISSIVE` uniform. +* Added new function `bbmod_shader_set_lightmap`, which sets the `BBMOD_U_LIGHTMAP` uniform. +* Added new function `bbmod_shader_set_base_opacity_uv`, which sets the `BBMOD_U_BASE_OPACITY_UV` uniform. +* Added new function `bbmod_shader_set_normal_w_uv`, which sets the `BBMOD_U_NORMAL_W_UV` uniform. +* Added new function `bbmod_shader_set_material_uv`, which sets the `BBMOD_U_MATERIAL_UV` uniform. +* Added new function `bbmod_shader_set_alpha_test`, which sets the `BBMOD_U_ALPHA_TEST` uniform. +* Added new function `bbmod_shader_set_cam_pos`, which sets the `BBMOD_U_CAM_POS` uniform. +* Added new function `bbmod_shader_set_zfar`, which sets the `BBMOD_U_ZFAR` uniform. +* Added new function `bbmod_shader_set_exposure`, which sets the `BBMOD_U_EXPOSURE` uniform. +* Added new function `bbmod_shader_set_soft_distance`, which sets the `BBMOD_U_SOFT_DISTANCE` uniform. +* Added new function `bbmod_shader_set_fog`, which sets uniforms `BBMOD_U_FOG_COLOR`, `BBMOD_U_FOG_INTENSITY`, `BBMOD_U_FOG_START` and `BBMOD_U_FOG_RCP_RANGE`. +* Added new function `bbmod_shader_set_ambient_light`, which sets uniforms `BBMOD_U_LIGHT_AMBIENT_UP`, `BBMOD_U_LIGHT_AMBIENT_DOWN` and `BBMOD_U_LIGHT_AMBIENT_DIR_UP`. +* Added new function `bbmod_shader_set_directional_light`, which sets uniforms `BBMOD_U_LIGHT_DIRECTIONAL_DIR` and `BBMOD_U_LIGHT_DIRECTIONAL_COLOR`. +* Added new function `bbmod_shader_set_ssao`, which sets the `BBMOD_U_SSAO` uniform. +* Added new function `bbmod_shader_set_ibl`, which sets uniforms `BBMOD_U_IBL_ENABLE`, `BBMOD_U_IBL_TEXEL` and `BBMOD_U_IBL`. +* Added new function `bbmod_shader_set_punctual_lights`, which sets uniforms `BBMOD_U_LIGHT_PUNCTUAL_DATA_A` and `BBMOD_U_LIGHT_PUNCTUAL_DATA_B`. +* Added new function `bbmod_shader_set_shadowmap_bias`, which sets the `BBMOD_U_SHADOWMAP_BIAS` uniform. +* Added new function `bbmod_shader_set_hdr`, which sets the `BBMOD_U_HDR` uniform. +* Method `set_texture_offset` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_texture_offset` instead. +* Method `set_texture_scale` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_texture_scale` instead. +* Method `set_bones` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_bones` instead. +* Method `set_batch_data` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_batch_data` instead. +* Method `set_alpha_test` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_alpha_test` instead. +* Method `set_cam_pos` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_cam_pos` instead. +* Method `set_exposure` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_exposure` instead. +* Method `set_set_instance_id` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_instance_id` instead. +* Method `set_set_material_index` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_material_index` instead. +* Method `set_set_ibl` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_ibl` instead. +* Method `set_ambient_light` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_ambient_light` instead. +* Method `set_directional_light` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_directional_light` instead. +* Method `set_punctual_lights` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_punctual_lights` instead. +* Method `set_fog` of `BBMOD_BaseShader` is now **deprecated**! Please use the new function `bbmod_shader_set_fog` instead. +* Method `set_normal_smoothness` of `BBMOD_DefaultShader` is now **deprecated**! Please use the new function `bbmod_shader_set_normal_smoothness` instead. +* Method `set_specular_color` of `BBMOD_DefaultShader` is now **deprecated**! Please use the new function `bbmod_shader_set_specular_color` instead. +* Method `set_normal_roughness` of `BBMOD_DefaultShader` is now **deprecated**! Please use the new function `bbmod_shader_set_normal_roughness` instead. +* Method `set_metallic_ao` of `BBMOD_DefaultShader` is now **deprecated**! Please use the new function `bbmod_shader_set_metallic_ao` instead. +* Method `set_subsurface` of `BBMOD_DefaultShader` is now **deprecated**! Please use the new function `bbmod_shader_set_subsurface` instead. +* Method `set_emissive` of `BBMOD_DefaultShader` is now **deprecated**! Please use the new function `bbmod_shader_set_emissive` instead. +* Method `set_lightmap` of `BBMOD_DefaultLightmapShader` is now **deprecated**! Please use the new function `bbmod_shader_set_lightmap` instead. +* Fixed `BBMOD_PunctualLight` not affecting particles by default. +* Fixed function `bbmod_mrt_is_supported` not working on Mac. +* Fixed method `clone` of `BBMOD_TerrainMaterial`, which returned instances of `BBMOD_BaseMaterial`. +* Fixed materials with `AlphaBlend` enabled not working in the `Id` render pass. diff --git a/docs_src/Changelog/Changelog_.md b/docs_src/Changelog/Changelog_.md index 270d5236..73f160ee 100644 --- a/docs_src/Changelog/Changelog_.md +++ b/docs_src/Changelog/Changelog_.md @@ -2,6 +2,7 @@ In this section you can find changelogs for all releases of BBMOD since 3.0.0. ## Contents +* [3.20.0](./Changelog3.20.0.html) * [3.19.3](./Changelog3.19.3.html) * [3.19.2](./Changelog3.19.2.html) * [3.19.1](./Changelog3.19.1.html) diff --git a/docs_src/Modules/DeferredRendererModule.md b/docs_src/Modules/DeferredRendererModule.md new file mode 100644 index 00000000..e97d9c49 --- /dev/null +++ b/docs_src/Modules/DeferredRendererModule.md @@ -0,0 +1,10 @@ +# Deferred renderer module +This module contains a deferred rendering pipeline with support for unlimited +number of shadow-casting lights. + +## Scripting API + diff --git a/docs_src/Modules/Modules.md b/docs_src/Modules/Modules.md index 68a71e7c..5500acd9 100644 --- a/docs_src/Modules/Modules.md +++ b/docs_src/Modules/Modules.md @@ -8,6 +8,7 @@ individual modules. ## Contents * [Core module](./CoreModule.html) +* [Deferred renderer module](./DeferredRendererModule.html) * [Gizmo module](./GizmoModule.html) * [OBJ importer module](./OBJImporterModule.html) * [Particles module](./ParticlesModule.html) diff --git a/docs_src/index.md b/docs_src/index.md index b44e0980..f6d46b4e 100644 --- a/docs_src/index.md +++ b/docs_src/index.md @@ -1,5 +1,5 @@ # BBMOD -Welcome to the official documentation of BBMOD 3.19.3! +Welcome to the official documentation of BBMOD 3.20.0! BBMOD is an advanced 3D rendering solution for GameMaker. It consists of a custom model, animation and material formats, a model converter (BBMOD CLI), diff --git a/gmdoc.json b/gmdoc.json index 565076b6..56d97a19 100644 --- a/gmdoc.json +++ b/gmdoc.json @@ -5,7 +5,7 @@ "title": "BBMOD Docs", "author": "BlueBurn", "prefix": ["bbmod", "__bbmod"], - "version": "3.19.3", + "version": "3.20.0", "analytics": "", "api": { "rating": "/bbmod/page_rating.php" @@ -15,6 +15,7 @@ "Changelog": { "file": "Changelog/Changelog_.md", "pages": { + "3.20.0": "Changelog/Changelog3.20.0.md", "3.19.3": "Changelog/Changelog3.19.3.md", "3.19.2": "Changelog/Changelog3.19.2.md", "3.19.1": "Changelog/Changelog3.19.1.md", @@ -84,6 +85,7 @@ "file": "Modules/Modules.md", "pages": { "Core module": "Modules/CoreModule.md", + "Deferred renderer module": "Modules/DeferredRendererModule.md", "Gizmo module": "Modules/GizmoModule.md", "OBJ importer module": "Modules/OBJImporterModule.md", "Particles module": "Modules/ParticlesModule.md",