1 /* 2 Copyright (c) 2019-2022 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 module dagon.render.shaders.terrain; 28 29 import std.stdio; 30 import std.math; 31 32 import dlib.core.memory; 33 import dlib.core.ownership; 34 import dlib.math.vector; 35 import dlib.math.matrix; 36 import dlib.math.transformation; 37 import dlib.math.interpolation; 38 import dlib.image.color; 39 import dlib.text.str; 40 41 import dagon.core.bindings; 42 import dagon.graphics.material; 43 import dagon.graphics.shader; 44 import dagon.graphics.state; 45 import dagon.graphics.texture; 46 import dagon.graphics.terrain; 47 48 class TerrainGeometryShader: Shader 49 { 50 String vs, fs; 51 52 this(Owner owner) 53 { 54 vs = Shader.load("data/__internal/shaders/Terrain/TerrainGeometry.vert.glsl"); 55 fs = Shader.load("data/__internal/shaders/Terrain/TerrainGeometry.frag.glsl"); 56 57 auto prog = New!ShaderProgram(vs, fs, this); 58 super(prog, owner); 59 } 60 61 ~this() 62 { 63 vs.free(); 64 fs.free(); 65 } 66 67 override void bindParameters(GraphicsState* state) 68 { 69 Material mat = state.material; 70 71 setParameter("modelViewMatrix", state.modelViewMatrix); 72 setParameter("projectionMatrix", state.projectionMatrix); 73 setParameter("normalMatrix", state.normalMatrix); 74 setParameter("viewMatrix", state.viewMatrix); 75 setParameter("invViewMatrix", state.invViewMatrix); 76 setParameter("prevModelViewMatrix", state.prevModelViewMatrix); 77 78 setParameter("gbufferMask", 1.0f); 79 setParameter("blurMask", state.blurMask); 80 81 super.bindParameters(state); 82 } 83 84 override void unbindParameters(GraphicsState* state) 85 { 86 super.unbindParameters(state); 87 } 88 } 89 90 class TerrainTextureLayerShader: Shader 91 { 92 String vs, fs; 93 94 this(Owner owner) 95 { 96 vs = Shader.load("data/__internal/shaders/Terrain/TerrainTextureLayer.vert.glsl"); 97 fs = Shader.load("data/__internal/shaders/Terrain/TerrainTextureLayer.frag.glsl"); 98 99 auto prog = New!ShaderProgram(vs, fs, this); 100 super(prog, owner); 101 } 102 103 ~this() 104 { 105 vs.free(); 106 fs.free(); 107 } 108 109 override void bindParameters(GraphicsState* state) 110 { 111 Material mat = state.material; 112 113 setParameter("viewMatrix", state.viewMatrix); 114 setParameter("invViewMatrix", state.invViewMatrix); 115 setParameter("projectionMatrix", state.projectionMatrix); 116 setParameter("invProjectionMatrix", state.invProjectionMatrix); 117 setParameter("resolution", state.resolution); 118 setParameter("zNear", state.zNear); 119 setParameter("zFar", state.zFar); 120 121 setParameter("opacity", mat.opacity); 122 setParameter("textureScale", mat.textureScale); 123 setParameter("clipThreshold", mat.alphaTestThreshold); 124 125 // Texture 0 - normal buffer 126 glActiveTexture(GL_TEXTURE0); 127 glBindTexture(GL_TEXTURE_2D, state.normalTexture); 128 setParameter("terrainNormalBuffer", cast(int)0); 129 130 // Texture 1 - texcoord buffer 131 glActiveTexture(GL_TEXTURE1); 132 glBindTexture(GL_TEXTURE_2D, state.texcoordTexture); 133 setParameter("terrainTexcoordBuffer", cast(int)1); 134 135 // Texture 2 - mask 136 glActiveTexture(GL_TEXTURE2); 137 setParameter("maskTexture", cast(int)2); 138 setParameter("maskFactor", mat.maskFactor); 139 if (mat.maskTexture) 140 { 141 mat.maskTexture.bind(); 142 setParameterSubroutine("layerMask", ShaderType.Fragment, "layerMaskTexture"); 143 } 144 else 145 { 146 glBindTexture(GL_TEXTURE_2D, 0); 147 setParameterSubroutine("layerMask", ShaderType.Fragment, "layerMaskValue"); 148 } 149 150 // Diffuse 151 glActiveTexture(GL_TEXTURE3); 152 setParameter("diffuseTexture", cast(int)3); 153 setParameter("diffuseVector", mat.baseColorFactor); 154 if (mat.baseColorTexture) 155 { 156 mat.baseColorTexture.bind(); 157 setParameterSubroutine("diffuse", ShaderType.Fragment, "diffuseColorTexture"); 158 } 159 else 160 { 161 glBindTexture(GL_TEXTURE_2D, 0); 162 setParameterSubroutine("diffuse", ShaderType.Fragment, "diffuseColorValue"); 163 } 164 165 // Normal 166 glActiveTexture(GL_TEXTURE4); 167 setParameter("normalTexture", cast(int)4); 168 setParameter("normalVector", mat.normalFactor); 169 if (mat.normalTexture) 170 { 171 mat.normalTexture.bind(); 172 setParameterSubroutine("normal", ShaderType.Fragment, "normalMap"); 173 setParameter("generateTBN", cast(int)1); 174 } 175 else 176 { 177 glBindTexture(GL_TEXTURE_2D, 0); 178 setParameterSubroutine("normal", ShaderType.Fragment, "normalValue"); 179 setParameter("generateTBN", cast(int)0); 180 } 181 182 if (state.material.invertNormalY) 183 setParameter("normalYSign", -1.0f); 184 else 185 setParameter("normalYSign", 1.0f); 186 187 // Height and parallax 188 int parallaxMethod = mat.parallaxMode; 189 if (parallaxMethod > ParallaxOcclusionMapping) 190 parallaxMethod = ParallaxOcclusionMapping; 191 if (parallaxMethod < 0) 192 parallaxMethod = 0; 193 194 glActiveTexture(GL_TEXTURE5); 195 setParameter("heightTexture", cast(int)5); 196 setParameter("heightScalar", mat.heightFactor); 197 if (mat.heightTexture) 198 { 199 mat.heightTexture.bind(); 200 setParameterSubroutine("height", ShaderType.Fragment, "heightMap"); 201 } 202 else 203 { 204 glBindTexture(GL_TEXTURE_2D, 0); 205 setParameterSubroutine("height", ShaderType.Fragment, "heightValue"); 206 parallaxMethod = ParallaxNone; 207 } 208 209 if (parallaxMethod == ParallaxSimple) 210 setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxSimple"); 211 else if (parallaxMethod == ParallaxOcclusionMapping) 212 setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxOcclusionMapping"); 213 else 214 setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxNone"); 215 216 setParameter("parallaxScale", mat.parallaxScale); 217 setParameter("parallaxBias", mat.parallaxBias); 218 219 // PBR 220 glActiveTexture(GL_TEXTURE6); 221 setParameter("roughnessMetallicTexture", cast(int)6); 222 setParameter("roughnessMetallicFactor", Vector4f(1.0f, mat.roughnessFactor, mat.metallicFactor, 0.0f)); 223 if (mat.roughnessMetallicTexture) 224 { 225 mat.roughnessMetallicTexture.bind(); 226 setParameterSubroutine("roughness", ShaderType.Fragment, "roughnessMap"); 227 setParameterSubroutine("metallic", ShaderType.Fragment, "metallicMap"); 228 } 229 else 230 { 231 glBindTexture(GL_TEXTURE_2D, 0); 232 setParameterSubroutine("roughness", ShaderType.Fragment, "roughnessValue"); 233 setParameterSubroutine("metallic", ShaderType.Fragment, "metallicValue"); 234 } 235 236 // Emission 237 glActiveTexture(GL_TEXTURE7); 238 setParameter("emissionTexture", cast(int)7); 239 setParameter("emissionFactor", mat.emissionFactor); 240 if (mat.emissionTexture) 241 { 242 mat.emissionTexture.bind(); 243 setParameterSubroutine("emission", ShaderType.Fragment, "emissionColorTexture"); 244 } 245 else 246 { 247 glBindTexture(GL_TEXTURE_2D, 0); 248 setParameterSubroutine("emission", ShaderType.Fragment, "emissionColorValue"); 249 } 250 setParameter("energy", mat.emissionEnergy); 251 252 super.bindParameters(state); 253 254 glActiveTexture(GL_TEXTURE0); 255 } 256 257 override void unbindParameters(GraphicsState* state) 258 { 259 super.unbindParameters(state); 260 261 glActiveTexture(GL_TEXTURE0); 262 glBindTexture(GL_TEXTURE_2D, 0); 263 264 glActiveTexture(GL_TEXTURE1); 265 glBindTexture(GL_TEXTURE_2D, 0); 266 267 glActiveTexture(GL_TEXTURE2); 268 glBindTexture(GL_TEXTURE_2D, 0); 269 270 glActiveTexture(GL_TEXTURE3); 271 glBindTexture(GL_TEXTURE_2D, 0); 272 273 glActiveTexture(GL_TEXTURE4); 274 glBindTexture(GL_TEXTURE_2D, 0); 275 276 glActiveTexture(GL_TEXTURE5); 277 glBindTexture(GL_TEXTURE_2D, 0); 278 279 glActiveTexture(GL_TEXTURE6); 280 glBindTexture(GL_TEXTURE_2D, 0); 281 282 glActiveTexture(GL_TEXTURE7); 283 glBindTexture(GL_TEXTURE_2D, 0); 284 285 glActiveTexture(GL_TEXTURE0); 286 } 287 }