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 if (state.light) 117 { 118 auto light = state.light; 119 lightDirHg = Vector4f(light.directionAbsolute); 120 lightDirHg.w = 0.0; 121 lightColor = light.color; 122 lightEnergy = light.energy; 123 lightScattering = light.scatteringEnabled; 124 lightScatteringG = 1.0f - light.scattering; 125 lightScatteringDensity = light.mediumDensity; 126 lightScatteringSamples = light.scatteringSamples; 127 lightScatteringMaxRandomStepOffset = light.scatteringMaxRandomStepOffset; 128 lightScatteringShadow = light.scatteringUseShadow; 129 } 130 else 131 { 132 lightDirHg = Vector4f(0.0f, 0.0f, 1.0f, 0.0f); 133 lightColor = Color4f(1.0f, 1.0f, 1.0f, 1.0f); 134 } 135 Vector3f lightDir = (lightDirHg * state.viewMatrix).xyz; 136 setParameter("lightDirection", lightDir); 137 setParameter("lightColor", lightColor); 138 setParameter("lightEnergy", lightEnergy); 139 setParameter("lightScattering", lightScattering); 140 setParameter("lightScatteringG", lightScatteringG); 141 setParameter("lightScatteringDensity", lightScatteringDensity); 142 setParameter("lightScatteringSamples", lightScatteringSamples); 143 setParameter("lightScatteringMaxRandomStepOffset", lightScatteringMaxRandomStepOffset); 144 setParameter("lightScatteringShadow", lightScatteringShadow); 145 146 setParameter("time", state.localTime); 147 148 // Texture 0 - color buffer 149 glActiveTexture(GL_TEXTURE0); 150 glBindTexture(GL_TEXTURE_2D, state.colorTexture); 151 setParameter("colorBuffer", 0); 152 153 // Texture 1 - depth buffer 154 glActiveTexture(GL_TEXTURE1); 155 glBindTexture(GL_TEXTURE_2D, state.depthTexture); 156 setParameter("depthBuffer", 1); 157 158 // Texture 2 - normal buffer 159 glActiveTexture(GL_TEXTURE2); 160 glBindTexture(GL_TEXTURE_2D, state.normalTexture); 161 setParameter("normalBuffer", 2); 162 163 // Texture 3 - pbr buffer 164 glActiveTexture(GL_TEXTURE3); 165 glBindTexture(GL_TEXTURE_2D, state.pbrTexture); 166 setParameter("pbrBuffer", 3); 167 168 // Texture 4 - shadow map 169 if (state.light) 170 { 171 if (state.light.shadowEnabled) 172 { 173 CascadedShadowMap csm = cast(CascadedShadowMap)state.light.shadowMap; 174 175 glActiveTexture(GL_TEXTURE4); 176 glBindTexture(GL_TEXTURE_2D_ARRAY, csm.depthTexture); 177 setParameter("shadowTextureArray", 4); 178 setParameter("shadowResolution", cast(float)csm.resolution); 179 setParameter("shadowMatrix1", csm.area[0].shadowMatrix); 180 setParameter("shadowMatrix2", csm.area[1].shadowMatrix); 181 setParameter("shadowMatrix3", csm.area[2].shadowMatrix); 182 setParameterSubroutine("shadowMap", ShaderType.Fragment, "shadowMapCascaded"); 183 } 184 else 185 { 186 glActiveTexture(GL_TEXTURE4); 187 glBindTexture(GL_TEXTURE_2D_ARRAY, defaultShadowTexture); 188 setParameter("shadowTextureArray", 4); 189 setParameter("shadowMatrix1", defaultShadowMatrix); 190 setParameter("shadowMatrix2", defaultShadowMatrix); 191 setParameter("shadowMatrix3", defaultShadowMatrix); 192 setParameterSubroutine("shadowMap", ShaderType.Fragment, "shadowMapNone"); 193 } 194 } 195 196 // Texture 5 - occlusion buffer 197 if (glIsTexture(state.occlusionTexture)) 198 { 199 glActiveTexture(GL_TEXTURE5); 200 glBindTexture(GL_TEXTURE_2D, state.occlusionTexture); 201 setParameter("occlusionBuffer", 5); 202 setParameter("haveOcclusionBuffer", true); 203 } 204 else 205 { 206 setParameter("haveOcclusionBuffer", false); 207 } 208 209 glActiveTexture(GL_TEXTURE0); 210 211 super.bindParameters(state); 212 } 213 214 override void unbindParameters(GraphicsState* state) 215 { 216 super.unbindParameters(state); 217 218 glActiveTexture(GL_TEXTURE0); 219 glBindTexture(GL_TEXTURE_2D, 0); 220 221 glActiveTexture(GL_TEXTURE1); 222 glBindTexture(GL_TEXTURE_2D, 0); 223 224 glActiveTexture(GL_TEXTURE2); 225 glBindTexture(GL_TEXTURE_2D, 0); 226 227 glActiveTexture(GL_TEXTURE3); 228 glBindTexture(GL_TEXTURE_2D, 0); 229 230 glActiveTexture(GL_TEXTURE4); 231 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 232 233 glActiveTexture(GL_TEXTURE5); 234 glBindTexture(GL_TEXTURE_2D, 0); 235 236 glActiveTexture(GL_TEXTURE0); 237 } 238 }