1 /* 2 Copyright (c) 2019 Timur Gafarov 3 4 Boost Software License - Version 1.0 - August 17th, 2003 5 Permission is hereby granted, free of charge, to any person or organization 6 obtaining a copy of the software and accompanying documentation covered by 7 this license (the "Software") to use, reproduce, display, distribute, 8 execute, and transmit the Software, and to prepare derivative works of the 9 Software, and to permit third-parties to whom the Software is furnished to 10 do so, all subject to the following: 11 12 The copyright notices in the Software and this entire statement, including 13 the above license grant, this restriction and the following disclaimer, 14 must be included in all copies of the Software, in whole or in part, and 15 all derivative works of the Software, unless such copies or derivative 16 works are solely in the form of machine-executable object code generated by 17 a source language processor. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 */ 27 28 module dagon.graphics.shaders.sunlight; 29 30 import std.stdio; 31 import std.math; 32 33 import dlib.core.memory; 34 import dlib.math.vector; 35 import dlib.math.matrix; 36 import dlib.image.color; 37 38 import dagon.core.libs; 39 import dagon.core.ownership; 40 import dagon.graphics.rc; 41 import dagon.graphics.gbuffer; 42 import dagon.graphics.light; 43 import dagon.graphics.shadow; 44 import dagon.graphics.shader; 45 import dagon.graphics.framebuffer; 46 import dagon.graphics.cubemap; 47 48 class SunLightShader: Shader 49 { 50 string vs = import("SunLight.vs"); 51 string fs = import("SunLight.fs"); 52 53 GBuffer gbuffer; 54 LightSource light; 55 CascadedShadowMap shadowMap; 56 57 Matrix4x4f defaultShadowMatrix; 58 59 this(GBuffer gbuffer, Owner o) 60 { 61 auto myProgram = New!ShaderProgram(vs, fs, this); 62 super(myProgram, o); 63 this.gbuffer = gbuffer; 64 this.defaultShadowMatrix = Matrix4x4f.identity; 65 } 66 67 void bind(RenderingContext* rc2d, RenderingContext* rc3d) 68 { 69 setParameter("modelViewMatrix", rc2d.modelViewMatrix); 70 setParameter("projectionMatrix", rc2d.projectionMatrix); 71 72 setParameter("camProjectionMatrix", rc3d.projectionMatrix); 73 setParameter("camViewMatrix", rc3d.viewMatrix); 74 setParameter("camInvViewMatrix", rc3d.invViewMatrix); 75 76 setParameter("viewSize", Vector2f(gbuffer.width, gbuffer.height)); 77 78 if (light) 79 { 80 setParameter("sunDirection", light.directionEye(rc3d.viewMatrix)); 81 Color4f col = Color4f(light.color.x, light.color.y, light.color.z, 1.0f); 82 setParameter("sunColor", col); 83 setParameter("sunEnergy", light.energy); 84 } 85 86 // Texture 0 - color buffer 87 glActiveTexture(GL_TEXTURE0); 88 glBindTexture(GL_TEXTURE_2D, gbuffer.colorTexture); 89 setParameter("colorBuffer", 0); 90 91 // Texture 1 - roughness-metallic-specularity buffer 92 glActiveTexture(GL_TEXTURE1); 93 glBindTexture(GL_TEXTURE_2D, gbuffer.rmsTexture); 94 setParameter("rmsBuffer", 1); 95 96 // Texture 2 - position buffer 97 glActiveTexture(GL_TEXTURE2); 98 glBindTexture(GL_TEXTURE_2D, gbuffer.positionTexture); 99 setParameter("positionBuffer", 2); 100 101 // Texture 3 - normal buffer 102 glActiveTexture(GL_TEXTURE3); 103 glBindTexture(GL_TEXTURE_2D, gbuffer.normalTexture); 104 setParameter("normalBuffer", 3); 105 106 // Texture 5 - emission buffer 107 glActiveTexture(GL_TEXTURE5); 108 glBindTexture(GL_TEXTURE_2D, gbuffer.emissionTexture); 109 setParameter("emissionBuffer", 5); 110 111 // Texture 6 - shadow map cascades (3 layer texture array) 112 if (light) 113 { 114 if (light.shadow && light.shadowMap) 115 { 116 auto cascadedShadowMap = cast(CascadedShadowMap)light.shadowMap; 117 glActiveTexture(GL_TEXTURE6); 118 glBindTexture(GL_TEXTURE_2D_ARRAY, cascadedShadowMap.depthTexture); 119 setParameter("shadowTextureArray", 6); 120 setParameter("shadowTextureSize", cast(float)cascadedShadowMap.size); 121 setParameter("shadowMatrix1", cascadedShadowMap.area1.shadowMatrix); 122 setParameter("shadowMatrix2", cascadedShadowMap.area2.shadowMatrix); 123 setParameter("shadowMatrix3", cascadedShadowMap.area3.shadowMatrix); 124 setParameter("eyeSpaceNormalShift", cascadedShadowMap.eyeSpaceNormalShift); 125 126 setParameterSubroutine("shadowMap", ShaderType.Fragment, "shadowMapCascaded"); 127 } 128 else 129 { 130 setParameter("shadowMatrix1", defaultShadowMatrix); 131 setParameter("shadowMatrix2", defaultShadowMatrix); 132 setParameter("shadowMatrix3", defaultShadowMatrix); 133 134 setParameterSubroutine("shadowMap", ShaderType.Fragment, "shadowMapNone"); 135 } 136 } 137 138 glActiveTexture(GL_TEXTURE0); 139 140 super.bind(rc2d); 141 } 142 143 void unbind(RenderingContext* rc2d, RenderingContext* rc3d) 144 { 145 super.unbind(rc2d); 146 147 glActiveTexture(GL_TEXTURE0); 148 glBindTexture(GL_TEXTURE_2D, 0); 149 150 glActiveTexture(GL_TEXTURE1); 151 glBindTexture(GL_TEXTURE_2D, 0); 152 153 glActiveTexture(GL_TEXTURE2); 154 glBindTexture(GL_TEXTURE_2D, 0); 155 156 glActiveTexture(GL_TEXTURE3); 157 glBindTexture(GL_TEXTURE_2D, 0); 158 159 glActiveTexture(GL_TEXTURE5); 160 glBindTexture(GL_TEXTURE_2D, 0); 161 162 glActiveTexture(GL_TEXTURE6); 163 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 164 165 glActiveTexture(GL_TEXTURE7); 166 glBindTexture(GL_TEXTURE_2D, 0); 167 168 glActiveTexture(GL_TEXTURE0); 169 } 170 }