1 /* 2 Copyright (c) 2019-2023 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.environment; 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 46 class EnvironmentShader: Shader 47 { 48 String vs, fs; 49 50 this(Owner owner) 51 { 52 vs = Shader.load("data/__internal/shaders/Environment/Environment.vert.glsl"); 53 fs = Shader.load("data/__internal/shaders/Environment/Environment.frag.glsl"); 54 55 auto myProgram = New!ShaderProgram(vs, fs, this); 56 super(myProgram, owner); 57 } 58 59 ~this() 60 { 61 vs.free(); 62 fs.free(); 63 } 64 65 override void bindParameters(GraphicsState* state) 66 { 67 setParameter("viewMatrix", state.viewMatrix); 68 setParameter("invViewMatrix", state.invViewMatrix); 69 setParameter("projectionMatrix", state.projectionMatrix); 70 setParameter("invProjectionMatrix", state.invProjectionMatrix); 71 setParameter("resolution", state.resolution); 72 setParameter("zNear", state.zNear); 73 setParameter("zFar", state.zFar); 74 75 // Texture 0 - color buffer 76 glActiveTexture(GL_TEXTURE0); 77 glBindTexture(GL_TEXTURE_2D, state.colorTexture); 78 setParameter("colorBuffer", cast(int)0); 79 80 // Texture 1 - depth buffer 81 glActiveTexture(GL_TEXTURE1); 82 glBindTexture(GL_TEXTURE_2D, state.depthTexture); 83 setParameter("depthBuffer", cast(int)1); 84 85 // Texture 2 - normal buffer 86 glActiveTexture(GL_TEXTURE2); 87 glBindTexture(GL_TEXTURE_2D, state.normalTexture); 88 setParameter("normalBuffer", cast(int)2); 89 90 // Texture 3 - pbr buffer 91 glActiveTexture(GL_TEXTURE3); 92 glBindTexture(GL_TEXTURE_2D, state.pbrTexture); 93 setParameter("pbrBuffer", cast(int)3); 94 95 // Textures 4, 5 - environment (equirectangular map, cube map) 96 if (state.environment) 97 { 98 setParameter("fogColor", state.environment.fogColor); 99 setParameter("fogStart", state.environment.fogStart); 100 setParameter("fogEnd", state.environment.fogEnd); 101 setParameter("ambientEnergy", state.environment.ambientEnergy); 102 103 if (state.environment.ambientMap) 104 { 105 if (state.environment.ambientMap.isCubemap) 106 { 107 glActiveTexture(GL_TEXTURE4); 108 glBindTexture(GL_TEXTURE_2D, 0); 109 setParameter("ambientTexture", cast(int)4); 110 111 glActiveTexture(GL_TEXTURE5); 112 state.environment.ambientMap.bind(); 113 setParameter("ambientTextureCube", cast(int)5); 114 115 setParameterSubroutine("ambient", ShaderType.Fragment, "ambientCubemap"); 116 } 117 else 118 { 119 glActiveTexture(GL_TEXTURE4); 120 state.environment.ambientMap.bind(); 121 setParameter("ambientTexture", cast(int)4); 122 123 glActiveTexture(GL_TEXTURE5); 124 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 125 setParameter("ambientTextureCube", cast(int)5); 126 127 setParameterSubroutine("ambient", ShaderType.Fragment, "ambientEquirectangularMap"); 128 } 129 } 130 else 131 { 132 glActiveTexture(GL_TEXTURE4); 133 glBindTexture(GL_TEXTURE_2D, 0); 134 setParameter("ambientTexture", cast(int)4); 135 136 glActiveTexture(GL_TEXTURE5); 137 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 138 setParameter("ambientTextureCube", cast(int)5); 139 140 setParameter("ambientVector", state.environment.ambientColor); 141 142 setParameterSubroutine("ambient", ShaderType.Fragment, "ambientColor"); 143 } 144 } 145 else 146 { 147 setParameter("fogColor", Color4f(0.5f, 0.5f, 0.5f, 1.0f)); 148 setParameter("fogStart", 0.0f); 149 setParameter("fogEnd", 1000.0f); 150 setParameter("ambientEnergy", 1.0f); 151 setParameter("ambientVector", Color4f(0.5f, 0.5f, 0.5f, 1.0f)); 152 153 glActiveTexture(GL_TEXTURE4); 154 glBindTexture(GL_TEXTURE_2D, 0); 155 setParameter("ambientTexture", cast(int)4); 156 157 glActiveTexture(GL_TEXTURE5); 158 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 159 setParameter("ambientTextureCube", cast(int)5); 160 161 setParameterSubroutine("ambient", ShaderType.Fragment, "ambientColor"); 162 } 163 164 // Texture 6 - occlusion buffer 165 glActiveTexture(GL_TEXTURE6); 166 if (glIsTexture(state.occlusionTexture)) 167 { 168 glBindTexture(GL_TEXTURE_2D, state.occlusionTexture); 169 setParameter("occlusionBuffer", cast(int)6); 170 setParameter("haveOcclusionBuffer", true); 171 } 172 else 173 { 174 glBindTexture(GL_TEXTURE_2D, 0); 175 setParameter("occlusionBuffer", cast(int)6); 176 setParameter("haveOcclusionBuffer", false); 177 } 178 179 // Texture 7 - environment BRDF LUT 180 glActiveTexture(GL_TEXTURE7); 181 if (state.environment) 182 { 183 if (state.environment.ambientBRDF) 184 { 185 state.environment.ambientBRDF.bind(); 186 setParameter("ambientBRDF", cast(int)7); 187 setParameter("haveAmbientBRDF", true); 188 } 189 else 190 { 191 glBindTexture(GL_TEXTURE_2D, 0); 192 setParameter("ambientBRDF", cast(int)7); 193 setParameter("haveAmbientBRDF", false); 194 } 195 } 196 else 197 { 198 setParameter("haveAmbientBRDF", false); 199 } 200 201 glActiveTexture(GL_TEXTURE0); 202 203 super.bindParameters(state); 204 } 205 206 override void unbindParameters(GraphicsState* state) 207 { 208 super.unbindParameters(state); 209 210 glActiveTexture(GL_TEXTURE0); 211 glBindTexture(GL_TEXTURE_2D, 0); 212 213 glActiveTexture(GL_TEXTURE1); 214 glBindTexture(GL_TEXTURE_2D, 0); 215 216 glActiveTexture(GL_TEXTURE2); 217 glBindTexture(GL_TEXTURE_2D, 0); 218 219 glActiveTexture(GL_TEXTURE3); 220 glBindTexture(GL_TEXTURE_2D, 0); 221 222 glActiveTexture(GL_TEXTURE4); 223 glBindTexture(GL_TEXTURE_2D, 0); 224 225 glActiveTexture(GL_TEXTURE5); 226 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 227 228 glActiveTexture(GL_TEXTURE6); 229 glBindTexture(GL_TEXTURE_2D, 0); 230 231 glActiveTexture(GL_TEXTURE7); 232 glBindTexture(GL_TEXTURE_2D, 0); 233 234 glActiveTexture(GL_TEXTURE0); 235 } 236 }