1 /* 2 Copyright (c) 2019-2020 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.render.shaders.sunlight; 29 30 import std.stdio; 31 import std.math; 32 33 import dlib.core.memory; 34 import dlib.core.ownership; 35 import dlib.math.vector; 36 import dlib.math.matrix; 37 import dlib.math.transformation; 38 import dlib.math.interpolation; 39 import dlib.image.color; 40 import dlib.text.str; 41 42 import dagon.core.bindings; 43 import dagon.graphics.shader; 44 import dagon.graphics.state; 45 import dagon.graphics.csm; 46 47 class SunLightShader: Shader 48 { 49 String vs, fs; 50 51 Matrix4x4f defaultShadowMatrix; 52 GLuint defaultShadowTexture; 53 54 this(Owner owner) 55 { 56 vs = Shader.load("data/__internal/shaders/SunLight/SunLight.vert.glsl"); 57 fs = Shader.load("data/__internal/shaders/SunLight/SunLight.frag.glsl"); 58 59 auto myProgram = New!ShaderProgram(vs, fs, this); 60 super(myProgram, owner); 61 62 defaultShadowMatrix = Matrix4x4f.identity; 63 64 glGenTextures(1, &defaultShadowTexture); 65 glActiveTexture(GL_TEXTURE0); 66 glBindTexture(GL_TEXTURE_2D_ARRAY, defaultShadowTexture); 67 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, 1, 1, 3, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null); 68 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 69 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 70 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 71 } 72 73 ~this() 74 { 75 if (glIsFramebuffer(defaultShadowTexture)) 76 glDeleteFramebuffers(1, &defaultShadowTexture); 77 78 vs.free(); 79 fs.free(); 80 } 81 82 override void bindParameters(GraphicsState* state) 83 { 84 setParameter("viewMatrix", state.viewMatrix); 85 setParameter("invViewMatrix", state.invViewMatrix); 86 setParameter("projectionMatrix", state.projectionMatrix); 87 setParameter("invProjectionMatrix", state.invProjectionMatrix); 88 setParameter("resolution", state.resolution); 89 setParameter("zNear", state.zNear); 90 setParameter("zFar", state.zFar); 91 92 // Environment 93 if (state.environment) 94 { 95 setParameter("fogColor", state.environment.fogColor); 96 setParameter("fogStart", state.environment.fogStart); 97 setParameter("fogEnd", state.environment.fogEnd); 98 } 99 else 100 { 101 setParameter("fogColor", Color4f(0.5f, 0.5f, 0.5f, 1.0f)); 102 setParameter("fogStart", 0.0f); 103 setParameter("fogEnd", 1000.0f); 104 } 105 106 // Light 107 Vector4f lightDirHg; 108 Color4f lightColor; 109 float lightEnergy = 1.0f; 110 int lightScattering = 0; 111 float lightScatteringG = 0.0f; 112 float lightScatteringDensity = 0.0f; 113 int lightScatteringSamples = 1; 114 float lightScatteringMaxRandomStepOffset = 0.0f; 115 bool lightScatteringShadow = false; 116 float lightDiffuse = 1.0f; 117 float lightSpecular = 1.0f; 118 if (state.light) 119 { 120 auto light = state.light; 121 lightDirHg = Vector4f(light.directionAbsolute); 122 lightDirHg.w = 0.0; 123 lightColor = light.color; 124 lightEnergy = light.energy; 125 lightScattering = light.scatteringEnabled; 126 lightScatteringG = 1.0f - light.scattering; 127 lightScatteringDensity = light.mediumDensity; 128 lightScatteringSamples = light.scatteringSamples; 129 lightScatteringMaxRandomStepOffset = light.scatteringMaxRandomStepOffset; 130 lightScatteringShadow = light.scatteringUseShadow; 131 lightDiffuse = light.diffuse; 132 lightSpecular = light.specular; 133 } 134 else 135 { 136 lightDirHg = Vector4f(0.0f, 0.0f, 1.0f, 0.0f); 137 lightColor = Color4f(1.0f, 1.0f, 1.0f, 1.0f); 138 } 139 Vector3f lightDir = (lightDirHg * state.viewMatrix).xyz; 140 setParameter("lightDirection", lightDir); 141 setParameter("lightColor", lightColor); 142 setParameter("lightEnergy", lightEnergy); 143 setParameter("lightScattering", lightScattering); 144 setParameter("lightScatteringG", lightScatteringG); 145 setParameter("lightScatteringDensity", lightScatteringDensity); 146 setParameter("lightScatteringSamples", lightScatteringSamples); 147 setParameter("lightScatteringMaxRandomStepOffset", lightScatteringMaxRandomStepOffset); 148 setParameter("lightScatteringShadow", lightScatteringShadow); 149 150 setParameter("lightDiffuse", lightDiffuse); 151 setParameter("lightSpecular", lightSpecular); 152 153 setParameter("time", state.localTime); 154 155 // Texture 0 - color buffer 156 glActiveTexture(GL_TEXTURE0); 157 glBindTexture(GL_TEXTURE_2D, state.colorTexture); 158 setParameter("colorBuffer", 0); 159 160 // Texture 1 - depth buffer 161 glActiveTexture(GL_TEXTURE1); 162 glBindTexture(GL_TEXTURE_2D, state.depthTexture); 163 setParameter("depthBuffer", 1); 164 165 // Texture 2 - normal buffer 166 glActiveTexture(GL_TEXTURE2); 167 glBindTexture(GL_TEXTURE_2D, state.normalTexture); 168 setParameter("normalBuffer", 2); 169 170 // Texture 3 - pbr buffer 171 glActiveTexture(GL_TEXTURE3); 172 glBindTexture(GL_TEXTURE_2D, state.pbrTexture); 173 setParameter("pbrBuffer", 3); 174 175 // Texture 4 - shadow map 176 if (state.light) 177 { 178 if (state.light.shadowEnabled) 179 { 180 CascadedShadowMap csm = cast(CascadedShadowMap)state.light.shadowMap; 181 182 glActiveTexture(GL_TEXTURE4); 183 glBindTexture(GL_TEXTURE_2D_ARRAY, csm.depthTexture); 184 setParameter("shadowTextureArray", 4); 185 setParameter("shadowResolution", cast(float)csm.resolution); 186 setParameter("shadowMatrix1", csm.area[0].shadowMatrix); 187 setParameter("shadowMatrix2", csm.area[1].shadowMatrix); 188 setParameter("shadowMatrix3", csm.area[2].shadowMatrix); 189 setParameterSubroutine("shadowMap", ShaderType.Fragment, "shadowMapCascaded"); 190 } 191 else 192 { 193 glActiveTexture(GL_TEXTURE4); 194 glBindTexture(GL_TEXTURE_2D_ARRAY, defaultShadowTexture); 195 setParameter("shadowTextureArray", 4); 196 setParameter("shadowMatrix1", defaultShadowMatrix); 197 setParameter("shadowMatrix2", defaultShadowMatrix); 198 setParameter("shadowMatrix3", defaultShadowMatrix); 199 setParameterSubroutine("shadowMap", ShaderType.Fragment, "shadowMapNone"); 200 } 201 } 202 203 // Texture 5 - occlusion buffer 204 if (glIsTexture(state.occlusionTexture)) 205 { 206 glActiveTexture(GL_TEXTURE5); 207 glBindTexture(GL_TEXTURE_2D, state.occlusionTexture); 208 setParameter("occlusionBuffer", 5); 209 setParameter("haveOcclusionBuffer", true); 210 } 211 else 212 { 213 setParameter("haveOcclusionBuffer", false); 214 } 215 216 glActiveTexture(GL_TEXTURE0); 217 218 super.bindParameters(state); 219 } 220 221 override void unbindParameters(GraphicsState* state) 222 { 223 super.unbindParameters(state); 224 225 glActiveTexture(GL_TEXTURE0); 226 glBindTexture(GL_TEXTURE_2D, 0); 227 228 glActiveTexture(GL_TEXTURE1); 229 glBindTexture(GL_TEXTURE_2D, 0); 230 231 glActiveTexture(GL_TEXTURE2); 232 glBindTexture(GL_TEXTURE_2D, 0); 233 234 glActiveTexture(GL_TEXTURE3); 235 glBindTexture(GL_TEXTURE_2D, 0); 236 237 glActiveTexture(GL_TEXTURE4); 238 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 239 240 glActiveTexture(GL_TEXTURE5); 241 glBindTexture(GL_TEXTURE_2D, 0); 242 243 glActiveTexture(GL_TEXTURE0); 244 } 245 }