From d51cfc2489d2e37758f03ea44284e91029782a2f Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Thu, 1 Feb 2024 19:41:02 -0500 Subject: [PATCH] added pbr template --- assets/MatDefs/myMatDef.j3md | 303 ++++++++++++++++++ assets/Shaders/myFrag.frag | 368 ++++++++++++++++++++++ assets/Shaders/myVert.vert | 75 +++++ assets/Templates/pbrLightingFragment.temp | 368 ++++++++++++++++++++++ assets/Templates/pbrLightingMatDef.temp | 303 ++++++++++++++++++ assets/Templates/pbrLightingVertex.temp | 75 +++++ src/codex/shader/ShaderConfigApp.java | 166 ++++++---- src/codex/shader/Template.java | 33 +- src/codex/shader/TemplateKeyRenderer.java | 15 + 9 files changed, 1651 insertions(+), 55 deletions(-) create mode 100644 assets/MatDefs/myMatDef.j3md create mode 100644 assets/Shaders/myFrag.frag create mode 100644 assets/Shaders/myVert.vert create mode 100644 assets/Templates/pbrLightingFragment.temp create mode 100644 assets/Templates/pbrLightingMatDef.temp create mode 100644 assets/Templates/pbrLightingVertex.temp create mode 100644 src/codex/shader/TemplateKeyRenderer.java diff --git a/assets/MatDefs/myMatDef.j3md b/assets/MatDefs/myMatDef.j3md new file mode 100644 index 0000000..13358c8 --- /dev/null +++ b/assets/MatDefs/myMatDef.j3md @@ -0,0 +1,303 @@ +MaterialDef myMatDef { + + MaterialParameters { + Int BoundDrawBuffer + + // Alpha threshold for fragment discarding + Float AlphaDiscardThreshold (AlphaTestFallOff) + + //metallicity of the material + Float Metallic : 1.0 + //Roughness of the material + Float Roughness : 1.0 + // Base material color + Color BaseColor : 1.0 1.0 1.0 1.0 + // The emissive color of the object + Color Emissive + // the emissive power + Float EmissivePower : 3.0 + // the emissive intensity + Float EmissiveIntensity : 2.0 + + // BaseColor map + Texture2D BaseColorMap + + // Metallic map + Texture2D MetallicMap -LINEAR + + // Roughness Map + Texture2D RoughnessMap -LINEAR + + //Metallic and Roughness are packed respectively in the b and g channel of a single map + // r: AO (if AoPackedInMRMap is true) + // g: Roughness + // b: Metallic + Texture2D MetallicRoughnessMap -LINEAR + + // Texture of the emissive parts of the material + Texture2D EmissiveMap + + // Normal map + Texture2D NormalMap -LINEAR + // The scalar parameter applied to each normal vector of the normal map + Float NormalScale + + //The type of normal map: -1.0 (DirectX), 1.0 (OpenGl) + Float NormalType : -1.0 + + // For Spec gloss pipeline + Boolean UseSpecGloss + Texture2D SpecularMap + Texture2D GlossinessMap + Texture2D SpecularGlossinessMap + Color Specular : 1.0 1.0 1.0 1.0 + Float Glossiness : 1.0 + + // Parallax/height map + Texture2D ParallaxMap -LINEAR + + // Specular-AA + Boolean UseSpecularAA : true + // screen space variance,Use the slider to set the strength of the geometric specular anti-aliasing effect between 0 and 1. Higher values produce a blurrier result with less aliasing. + Float SpecularAASigma + // clamping threshold,Use the slider to set a maximum value for the offset that HDRP subtracts from the smoothness value to reduce artifacts. + Float SpecularAAKappa + + //Set to true if parallax map is stored in the alpha channel of the normal map + Boolean PackedNormalParallax + + //Sets the relief height for parallax mapping + Float ParallaxHeight : 0.05 + + //Set to true to activate Steep Parallax mapping + Boolean SteepParallax + + //Horizon fade + Boolean HorizonFade + + // Set to Use Lightmap + Texture2D LightMap + + // A scalar multiplier controlling the amount of occlusion applied. + // A value of `0.0` means no occlusion. A value of `1.0` means full occlusion. + Float AoStrength + + // Set to use TexCoord2 for the lightmap sampling + Boolean SeparateTexCoord + // the light map is a grayscale ao map, only the r channel will be read. + Boolean LightMapAsAOMap + Boolean AoPackedInMRMap + //shadows + Int FilterMode + Boolean HardwareShadows + + Texture2D ShadowMap0 + Texture2D ShadowMap1 + Texture2D ShadowMap2 + Texture2D ShadowMap3 + //pointLights + Texture2D ShadowMap4 + Texture2D ShadowMap5 + + Float ShadowIntensity + Vector4 Splits + Vector2 FadeInfo + + Matrix4 LightViewProjectionMatrix0 + Matrix4 LightViewProjectionMatrix1 + Matrix4 LightViewProjectionMatrix2 + Matrix4 LightViewProjectionMatrix3 + //pointLight + Matrix4 LightViewProjectionMatrix4 + Matrix4 LightViewProjectionMatrix5 + Vector3 LightPos + Vector3 LightDir + + Float PCFEdge + Float ShadowMapSize + + // For hardware skinning + Int NumberOfBones + Matrix4Array BoneMatrices + + // For Morph animation + FloatArray MorphWeights + Int NumberOfMorphTargets + Int NumberOfTargetsBuffers + + // For instancing + Boolean UseInstancing + + // For Vertex Color + Boolean UseVertexColor + + Boolean BackfaceShadows : false + } + + Technique { + LightMode SinglePassAndImageBased + + VertexShader GLSL300 GLSL150 GLSL110: Shaders/myVert.vert + FragmentShader GLSL300 GLSL150 GLSL110: Shaders/myFrag.frag + + WorldParameters { + WorldViewProjectionMatrix + CameraPosition + WorldMatrix + WorldNormalMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + BASECOLORMAP : BaseColorMap + NORMALMAP : NormalMap + NORMALSCALE : NormalScale + METALLICMAP : MetallicMap + ROUGHNESSMAP : RoughnessMap + EMISSIVEMAP : EmissiveMap + EMISSIVE : Emissive + SPECGLOSSPIPELINE : UseSpecGloss + PARALLAXMAP : ParallaxMap + NORMALMAP_PARALLAX : PackedNormalParallax + STEEP_PARALLAX : SteepParallax + LIGHTMAP : LightMap + SEPARATE_TEXCOORD : SeparateTexCoord + DISCARD_ALPHA : AlphaDiscardThreshold + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + USE_PACKED_MR: MetallicRoughnessMap + USE_PACKED_SG: SpecularGlossinessMap + SPECULARMAP : SpecularMap + SPECULAR_AA : UseSpecularAA + SPECULAR_AA_SCREEN_SPACE_VARIANCE : SpecularAASigma + SPECULAR_AA_THRESHOLD : SpecularAAKappa + GLOSSINESSMAP : GlossinessMap + NORMAL_TYPE: NormalType + VERTEX_COLOR : UseVertexColor + AO_MAP: LightMapAsAOMap + AO_PACKED_IN_MR_MAP : AoPackedInMRMap + AO_STRENGTH : AoStrength + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + HORIZON_FADE: HorizonFade + } + } + + + Technique PreShadow { + + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadowPBR.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + DISCARD_ALPHA : AlphaDiscardThreshold + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + ForcedRenderState { + FaceCull Off + DepthTest On + DepthWrite On + PolyOffset 5 3 + ColorWrite Off + } + + } + + + Technique PostShadow { + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowPBR.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + HARDWARE_SHADOWS : HardwareShadows + FILTER_MODE : FilterMode + PCFEDGE : PCFEdge + DISCARD_ALPHA : AlphaDiscardThreshold + SHADOWMAP_SIZE : ShadowMapSize + FADE : FadeInfo + PSSM : Splits + POINTLIGHT : LightViewProjectionMatrix5 + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + BACKFACE_SHADOWS: BackfaceShadows + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + ForcedRenderState { + Blend Modulate + DepthWrite Off + PolyOffset -0.1 0 + } + } + + Technique PreNormalPass { + + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + NormalMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + BASECOLORMAP_ALPHA : BaseColorMap + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + } + + Technique Glow { + + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/PBRGlow.frag + + WorldParameters { + WorldViewProjectionMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + HAS_EMISSIVEMAP : EmissiveMap + HAS_EMISSIVECOLOR : Emissive + BOUND_DRAW_BUFFER : BoundDrawBuffer + NEED_TEXCOORD1 + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + } + +} diff --git a/assets/Shaders/myFrag.frag b/assets/Shaders/myFrag.frag new file mode 100644 index 0000000..f7fc0d4 --- /dev/null +++ b/assets/Shaders/myFrag.frag @@ -0,0 +1,368 @@ + +#import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/PBR.glsllib" +#import "Common/ShaderLib/Parallax.glsllib" +#import "Common/ShaderLib/Lighting.glsllib" + +varying vec2 texCoord; +#ifdef SEPARATE_TEXCOORD + varying vec2 texCoord2; +#endif + +varying vec4 Color; + +uniform vec4 g_LightData[NB_LIGHTS]; +uniform vec3 g_CameraPosition; +uniform vec4 g_AmbientLightColor; + +uniform float m_Roughness; +uniform float m_Metallic; + +varying vec3 wPosition; + + +#if NB_PROBES >= 1 + uniform samplerCube g_PrefEnvMap; + uniform vec3 g_ShCoeffs[9]; + uniform mat4 g_LightProbeData; +#endif +#if NB_PROBES >= 2 + uniform samplerCube g_PrefEnvMap2; + uniform vec3 g_ShCoeffs2[9]; + uniform mat4 g_LightProbeData2; +#endif +#if NB_PROBES == 3 + uniform samplerCube g_PrefEnvMap3; + uniform vec3 g_ShCoeffs3[9]; + uniform mat4 g_LightProbeData3; +#endif + +#ifdef BASECOLORMAP + uniform sampler2D m_BaseColorMap; +#endif + +#ifdef USE_PACKED_MR + uniform sampler2D m_MetallicRoughnessMap; +#else + #ifdef METALLICMAP + uniform sampler2D m_MetallicMap; + #endif + #ifdef ROUGHNESSMAP + uniform sampler2D m_RoughnessMap; + #endif +#endif + +#ifdef EMISSIVE + uniform vec4 m_Emissive; +#endif +#ifdef EMISSIVEMAP + uniform sampler2D m_EmissiveMap; +#endif +#if defined(EMISSIVE) || defined(EMISSIVEMAP) + uniform float m_EmissivePower; + uniform float m_EmissiveIntensity; +#endif + +#ifdef SPECGLOSSPIPELINE + + uniform vec4 m_Specular; + uniform float m_Glossiness; + #ifdef USE_PACKED_SG + uniform sampler2D m_SpecularGlossinessMap; + #else + uniform sampler2D m_SpecularMap; + uniform sampler2D m_GlossinessMap; + #endif +#endif + +#ifdef PARALLAXMAP + uniform sampler2D m_ParallaxMap; +#endif +#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + uniform float m_ParallaxHeight; +#endif + +#ifdef LIGHTMAP + uniform sampler2D m_LightMap; +#endif + +#ifdef AO_STRENGTH + uniform float m_AoStrength; +#endif + +#if defined(NORMALMAP) || defined(PARALLAXMAP) + uniform sampler2D m_NormalMap; + varying vec4 wTangent; +#endif +#ifdef NORMALSCALE + uniform float m_NormalScale; +#endif +varying vec3 wNormal; + +// Specular-AA +#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + uniform float m_SpecularAASigma; +#endif +#ifdef SPECULAR_AA_THRESHOLD + uniform float m_SpecularAAKappa; +#endif + +#ifdef DISCARD_ALPHA + uniform float m_AlphaDiscardThreshold; +#endif + +void main(){ + vec2 newTexCoord; + vec3 viewDir = normalize(g_CameraPosition - wPosition); + + vec3 norm = normalize(wNormal); + #if defined(NORMALMAP) || defined(PARALLAXMAP) + vec3 tan = normalize(wTangent.xyz); + mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); + #endif + + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + vec3 vViewDir = viewDir * tbnMat; + #ifdef STEEP_PARALLAX + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #else + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #endif + #else + newTexCoord = texCoord; + #endif + + #ifdef BASECOLORMAP + vec4 albedo = texture2D(m_BaseColorMap, newTexCoord) * Color; + #else + vec4 albedo = Color; + #endif + + //ao in r channel, roughness in green channel, metallic in blue channel! + vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); + #ifdef USE_PACKED_MR + aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; + float Roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); + float Metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); + #else + #ifdef ROUGHNESSMAP + float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); + #else + float Roughness = max(m_Roughness, 1e-4); + #endif + #ifdef METALLICMAP + float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); + #else + float Metallic = max(m_Metallic, 0.0); + #endif + #endif + + float alpha = albedo.a; + + #ifdef DISCARD_ALPHA + if(alpha < m_AlphaDiscardThreshold){ + discard; + } + #endif + + // *********************** + // Read from textures + // *********************** + #if defined(NORMALMAP) + vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); + // Note we invert directx style normal maps to opengl style + + #ifdef NORMALSCALE + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); + #else + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); + #endif + normal = normalize(tbnMat * normal); + //normal = normalize(normal * inverse(tbnMat)); + #else + vec3 normal = norm; + #endif + + #ifdef SPECGLOSSPIPELINE + + #ifdef USE_PACKED_SG + vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); + float glossiness = specularColor.a * m_Glossiness; + specularColor *= m_Specular; + #else + #ifdef SPECULARMAP + vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + vec4 specularColor = vec4(1.0); + #endif + #ifdef GLOSSINESSMAP + float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness; + #else + float glossiness = m_Glossiness; + #endif + specularColor *= m_Specular; + #endif + vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); + Roughness = 1.0 - glossiness; + vec3 fZero = specularColor.xyz; + #else + float specular = 0.5; + float nonMetalSpec = 0.08 * specular; + vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; + vec4 diffuseColor = albedo - albedo * Metallic; + vec3 fZero = vec3(specular); + #endif + + gl_FragColor.rgb = vec3(0.0); + vec3 ao = vec3(1.0); + + #ifdef LIGHTMAP + vec3 lightMapColor; + #ifdef SEPARATE_TEXCOORD + lightMapColor = texture2D(m_LightMap, texCoord2).rgb; + #else + lightMapColor = texture2D(m_LightMap, texCoord).rgb; + #endif + #ifdef AO_MAP + lightMapColor.gb = lightMapColor.rr; + ao = lightMapColor; + #else + gl_FragColor.rgb += diffuseColor.rgb * lightMapColor; + #endif + specularColor.rgb *= lightMapColor; + #endif + + #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) + ao = aoRoughnessMetallicValue.rrr; + #endif + + #ifdef AO_STRENGTH + ao = 1.0 + m_AoStrength * (ao - 1.0); + // sanity check + ao = clamp(ao, 0.0, 1.0); + #endif + + #ifdef SPECULAR_AA + float sigma = 1.0; + float kappa = 0.18; + #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + sigma = m_SpecularAASigma; + #endif + #ifdef SPECULAR_AA_THRESHOLD + kappa = m_SpecularAAKappa; + #endif + #endif + float ndotv = max( dot( normal, viewDir ),0.0); + for( int i = 0;i < NB_LIGHTS; i+=3){ + vec4 lightColor = g_LightData[i]; + vec4 lightData1 = g_LightData[i+1]; + vec4 lightDir; + vec3 lightVec; + lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec); + + float fallOff = 1.0; + #if __VERSION__ >= 110 + // allow use of control flow + if(lightColor.w > 1.0){ + #endif + fallOff = computeSpotFalloff(g_LightData[i+2], lightVec); + #if __VERSION__ >= 110 + } + #endif + //point light attenuation + fallOff *= lightDir.w; + + lightDir.xyz = normalize(lightDir.xyz); + vec3 directDiffuse; + vec3 directSpecular; + + #ifdef SPECULAR_AA + float hdotv = PBR_ComputeDirectLightWithSpecularAA( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv, + directDiffuse, directSpecular); + #else + float hdotv = PBR_ComputeDirectLight( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, ndotv, + directDiffuse, directSpecular); + #endif + + vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular; + + gl_FragColor.rgb += directLighting * fallOff; + } + + #if NB_PROBES >= 1 + vec3 color1 = vec3(0.0); + vec3 color2 = vec3(0.0); + vec3 color3 = vec3(0.0); + float weight1 = 1.0; + float weight2 = 0.0; + float weight3 = 0.0; + + float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1); + #if NB_PROBES >= 2 + float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2); + #endif + #if NB_PROBES == 3 + float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3); + #endif + + #if NB_PROBES >= 2 + float invNdf = max(1.0 - ndf,0.0); + float invNdf2 = max(1.0 - ndf2,0.0); + float sumNdf = ndf + ndf2; + float sumInvNdf = invNdf + invNdf2; + #if NB_PROBES == 3 + float invNdf3 = max(1.0 - ndf3,0.0); + sumNdf += ndf3; + sumInvNdf += invNdf3; + weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf); + #endif + + weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf); + weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf); + + float weightSum = weight1 + weight2 + weight3; + + weight1 /= weightSum; + weight2 /= weightSum; + weight3 /= weightSum; + #endif + + #ifdef USE_AMBIENT_LIGHT + color1.rgb *= g_AmbientLightColor.rgb; + color2.rgb *= g_AmbientLightColor.rgb; + color3.rgb *= g_AmbientLightColor.rgb; + #endif + gl_FragColor.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0); + + #endif + + #if defined(EMISSIVE) || defined (EMISSIVEMAP) + #ifdef EMISSIVEMAP + vec4 emissive = texture2D(m_EmissiveMap, newTexCoord); + #ifdef EMISSIVE + emissive *= m_Emissive; + #endif + #else + vec4 emissive = m_Emissive; + #endif + gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; + #endif + gl_FragColor.a = alpha; + +} diff --git a/assets/Shaders/myVert.vert b/assets/Shaders/myVert.vert new file mode 100644 index 0000000..d4fbad2 --- /dev/null +++ b/assets/Shaders/myVert.vert @@ -0,0 +1,75 @@ + +#import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/Instancing.glsllib" +#import "Common/ShaderLib/Skinning.glsllib" +#import "Common/ShaderLib/MorphAnim.glsllib" + +uniform vec4 m_BaseColor; +uniform vec4 g_AmbientLightColor; +varying vec2 texCoord; + +#ifdef SEPARATE_TEXCOORD + varying vec2 texCoord2; + attribute vec2 inTexCoord2; +#endif + +varying vec4 Color; + +attribute vec3 inPosition; +attribute vec2 inTexCoord; +attribute vec3 inNormal; + +#ifdef VERTEX_COLOR + attribute vec4 inColor; +#endif + +varying vec3 wNormal; +varying vec3 wPosition; +#if defined(NORMALMAP) || defined(PARALLAXMAP) + attribute vec4 inTangent; + varying vec4 wTangent; +#endif + +void main(){ + vec4 modelSpacePos = vec4(inPosition, 1.0); + vec3 modelSpaceNorm = inNormal; + + #if ( defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING) + vec3 modelSpaceTan = inTangent.xyz; + #endif + + #ifdef NUM_MORPH_TARGETS + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + Morph_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan); + #else + Morph_Compute(modelSpacePos, modelSpaceNorm); + #endif + #endif + + #ifdef NUM_BONES + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan); + #else + Skinning_Compute(modelSpacePos, modelSpaceNorm); + #endif + #endif + + gl_Position = TransformWorldViewProjection(modelSpacePos); + texCoord = inTexCoord; + #ifdef SEPARATE_TEXCOORD + texCoord2 = inTexCoord2; + #endif + + wPosition = TransformWorld(modelSpacePos).xyz; + wNormal = TransformWorldNormal(modelSpaceNorm); + + #if defined(NORMALMAP) || defined(PARALLAXMAP) + wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); + #endif + + Color = m_BaseColor; + + #ifdef VERTEX_COLOR + Color *= inColor; + #endif +} diff --git a/assets/Templates/pbrLightingFragment.temp b/assets/Templates/pbrLightingFragment.temp new file mode 100644 index 0000000..e820e68 --- /dev/null +++ b/assets/Templates/pbrLightingFragment.temp @@ -0,0 +1,368 @@ + +#import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/PBR.glsllib" +#import "Common/ShaderLib/Parallax.glsllib" +#import "Common/ShaderLib/Lighting.glsllib" + +varying vec2 texCoord; +#ifdef SEPARATE_TEXCOORD + varying vec2 texCoord2; +#endif + +varying vec4 Color; + +uniform vec4 g_LightData[NB_LIGHTS]; +uniform vec3 g_CameraPosition; +uniform vec4 g_AmbientLightColor; + +uniform float m_Roughness; +uniform float m_Metallic; + +varying vec3 wPosition; + + +#if NB_PROBES >= 1 + uniform samplerCube g_PrefEnvMap; + uniform vec3 g_ShCoeffs[9]; + uniform mat4 g_LightProbeData; +#endif +#if NB_PROBES >= 2 + uniform samplerCube g_PrefEnvMap2; + uniform vec3 g_ShCoeffs2[9]; + uniform mat4 g_LightProbeData2; +#endif +#if NB_PROBES == 3 + uniform samplerCube g_PrefEnvMap3; + uniform vec3 g_ShCoeffs3[9]; + uniform mat4 g_LightProbeData3; +#endif + +#ifdef BASECOLORMAP + uniform sampler2D m_BaseColorMap; +#endif + +#ifdef USE_PACKED_MR + uniform sampler2D m_MetallicRoughnessMap; +#else + #ifdef METALLICMAP + uniform sampler2D m_MetallicMap; + #endif + #ifdef ROUGHNESSMAP + uniform sampler2D m_RoughnessMap; + #endif +#endif + +#ifdef EMISSIVE + uniform vec4 m_Emissive; +#endif +#ifdef EMISSIVEMAP + uniform sampler2D m_EmissiveMap; +#endif +#if defined(EMISSIVE) || defined(EMISSIVEMAP) + uniform float m_EmissivePower; + uniform float m_EmissiveIntensity; +#endif + +#ifdef SPECGLOSSPIPELINE + + uniform vec4 m_Specular; + uniform float m_Glossiness; + #ifdef USE_PACKED_SG + uniform sampler2D m_SpecularGlossinessMap; + #else + uniform sampler2D m_SpecularMap; + uniform sampler2D m_GlossinessMap; + #endif +#endif + +#ifdef PARALLAXMAP + uniform sampler2D m_ParallaxMap; +#endif +#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + uniform float m_ParallaxHeight; +#endif + +#ifdef LIGHTMAP + uniform sampler2D m_LightMap; +#endif + +#ifdef AO_STRENGTH + uniform float m_AoStrength; +#endif + +#if defined(NORMALMAP) || defined(PARALLAXMAP) + uniform sampler2D m_NormalMap; + varying vec4 wTangent; +#endif +#ifdef NORMALSCALE + uniform float m_NormalScale; +#endif +varying vec3 wNormal; + +// Specular-AA +#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + uniform float m_SpecularAASigma; +#endif +#ifdef SPECULAR_AA_THRESHOLD + uniform float m_SpecularAAKappa; +#endif + +#ifdef DISCARD_ALPHA + uniform float m_AlphaDiscardThreshold; +#endif + +void main(){ + vec2 newTexCoord; + vec3 viewDir = normalize(g_CameraPosition - wPosition); + + vec3 norm = normalize(wNormal); + #if defined(NORMALMAP) || defined(PARALLAXMAP) + vec3 tan = normalize(wTangent.xyz); + mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); + #endif + + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + vec3 vViewDir = viewDir * tbnMat; + #ifdef STEEP_PARALLAX + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #else + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #endif + #else + newTexCoord = texCoord; + #endif + + #ifdef BASECOLORMAP + vec4 albedo = texture2D(m_BaseColorMap, newTexCoord) * Color; + #else + vec4 albedo = Color; + #endif + + //ao in r channel, roughness in green channel, metallic in blue channel! + vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); + #ifdef USE_PACKED_MR + aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; + float Roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); + float Metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); + #else + #ifdef ROUGHNESSMAP + float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); + #else + float Roughness = max(m_Roughness, 1e-4); + #endif + #ifdef METALLICMAP + float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); + #else + float Metallic = max(m_Metallic, 0.0); + #endif + #endif + + float alpha = albedo.a; + + #ifdef DISCARD_ALPHA + if(alpha < m_AlphaDiscardThreshold){ + discard; + } + #endif + + // *********************** + // Read from textures + // *********************** + #if defined(NORMALMAP) + vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); + // Note we invert directx style normal maps to opengl style + + #ifdef NORMALSCALE + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); + #else + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); + #endif + normal = normalize(tbnMat * normal); + //normal = normalize(normal * inverse(tbnMat)); + #else + vec3 normal = norm; + #endif + + #ifdef SPECGLOSSPIPELINE + + #ifdef USE_PACKED_SG + vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); + float glossiness = specularColor.a * m_Glossiness; + specularColor *= m_Specular; + #else + #ifdef SPECULARMAP + vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + vec4 specularColor = vec4(1.0); + #endif + #ifdef GLOSSINESSMAP + float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness; + #else + float glossiness = m_Glossiness; + #endif + specularColor *= m_Specular; + #endif + vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); + Roughness = 1.0 - glossiness; + vec3 fZero = specularColor.xyz; + #else + float specular = 0.5; + float nonMetalSpec = 0.08 * specular; + vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; + vec4 diffuseColor = albedo - albedo * Metallic; + vec3 fZero = vec3(specular); + #endif + + gl_FragColor.rgb = vec3(0.0); + vec3 ao = vec3(1.0); + + #ifdef LIGHTMAP + vec3 lightMapColor; + #ifdef SEPARATE_TEXCOORD + lightMapColor = texture2D(m_LightMap, texCoord2).rgb; + #else + lightMapColor = texture2D(m_LightMap, texCoord).rgb; + #endif + #ifdef AO_MAP + lightMapColor.gb = lightMapColor.rr; + ao = lightMapColor; + #else + gl_FragColor.rgb += diffuseColor.rgb * lightMapColor; + #endif + specularColor.rgb *= lightMapColor; + #endif + + #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) + ao = aoRoughnessMetallicValue.rrr; + #endif + + #ifdef AO_STRENGTH + ao = 1.0 + m_AoStrength * (ao - 1.0); + // sanity check + ao = clamp(ao, 0.0, 1.0); + #endif + + #ifdef SPECULAR_AA + float sigma = 1.0; + float kappa = 0.18; + #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + sigma = m_SpecularAASigma; + #endif + #ifdef SPECULAR_AA_THRESHOLD + kappa = m_SpecularAAKappa; + #endif + #endif + float ndotv = max( dot( normal, viewDir ),0.0); + for( int i = 0;i < NB_LIGHTS; i+=3){ + vec4 lightColor = g_LightData[i]; + vec4 lightData1 = g_LightData[i+1]; + vec4 lightDir; + vec3 lightVec; + lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec); + + float fallOff = 1.0; + #if __VERSION__ >= 110 + // allow use of control flow + if(lightColor.w > 1.0){ + #endif + fallOff = computeSpotFalloff(g_LightData[i+2], lightVec); + #if __VERSION__ >= 110 + } + #endif + //point light attenuation + fallOff *= lightDir.w; + + lightDir.xyz = normalize(lightDir.xyz); + vec3 directDiffuse; + vec3 directSpecular; + + #ifdef SPECULAR_AA + float hdotv = PBR_ComputeDirectLightWithSpecularAA( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv, + directDiffuse, directSpecular); + #else + float hdotv = PBR_ComputeDirectLight( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, ndotv, + directDiffuse, directSpecular); + #endif + + vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular; + + gl_FragColor.rgb += directLighting * fallOff; + } + + #if NB_PROBES >= 1 + vec3 color1 = vec3(0.0); + vec3 color2 = vec3(0.0); + vec3 color3 = vec3(0.0); + float weight1 = 1.0; + float weight2 = 0.0; + float weight3 = 0.0; + + float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1); + #if NB_PROBES >= 2 + float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2); + #endif + #if NB_PROBES == 3 + float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3); + #endif + + #if NB_PROBES >= 2 + float invNdf = max(1.0 - ndf,0.0); + float invNdf2 = max(1.0 - ndf2,0.0); + float sumNdf = ndf + ndf2; + float sumInvNdf = invNdf + invNdf2; + #if NB_PROBES == 3 + float invNdf3 = max(1.0 - ndf3,0.0); + sumNdf += ndf3; + sumInvNdf += invNdf3; + weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf); + #endif + + weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf); + weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf); + + float weightSum = weight1 + weight2 + weight3; + + weight1 /= weightSum; + weight2 /= weightSum; + weight3 /= weightSum; + #endif + + #ifdef USE_AMBIENT_LIGHT + color1.rgb *= g_AmbientLightColor.rgb; + color2.rgb *= g_AmbientLightColor.rgb; + color3.rgb *= g_AmbientLightColor.rgb; + #endif + gl_FragColor.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0); + + #endif + + #if defined(EMISSIVE) || defined (EMISSIVEMAP) + #ifdef EMISSIVEMAP + vec4 emissive = texture2D(m_EmissiveMap, newTexCoord); + #ifdef EMISSIVE + emissive *= m_Emissive; + #endif + #else + vec4 emissive = m_Emissive; + #endif + gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; + #endif + gl_FragColor.a = alpha; + +} \ No newline at end of file diff --git a/assets/Templates/pbrLightingMatDef.temp b/assets/Templates/pbrLightingMatDef.temp new file mode 100644 index 0000000..563eb61 --- /dev/null +++ b/assets/Templates/pbrLightingMatDef.temp @@ -0,0 +1,303 @@ +MaterialDef [name] { + + MaterialParameters { + Int BoundDrawBuffer + + // Alpha threshold for fragment discarding + Float AlphaDiscardThreshold (AlphaTestFallOff) + + //metallicity of the material + Float Metallic : 1.0 + //Roughness of the material + Float Roughness : 1.0 + // Base material color + Color BaseColor : 1.0 1.0 1.0 1.0 + // The emissive color of the object + Color Emissive + // the emissive power + Float EmissivePower : 3.0 + // the emissive intensity + Float EmissiveIntensity : 2.0 + + // BaseColor map + Texture2D BaseColorMap + + // Metallic map + Texture2D MetallicMap -LINEAR + + // Roughness Map + Texture2D RoughnessMap -LINEAR + + //Metallic and Roughness are packed respectively in the b and g channel of a single map + // r: AO (if AoPackedInMRMap is true) + // g: Roughness + // b: Metallic + Texture2D MetallicRoughnessMap -LINEAR + + // Texture of the emissive parts of the material + Texture2D EmissiveMap + + // Normal map + Texture2D NormalMap -LINEAR + // The scalar parameter applied to each normal vector of the normal map + Float NormalScale + + //The type of normal map: -1.0 (DirectX), 1.0 (OpenGl) + Float NormalType : -1.0 + + // For Spec gloss pipeline + Boolean UseSpecGloss + Texture2D SpecularMap + Texture2D GlossinessMap + Texture2D SpecularGlossinessMap + Color Specular : 1.0 1.0 1.0 1.0 + Float Glossiness : 1.0 + + // Parallax/height map + Texture2D ParallaxMap -LINEAR + + // Specular-AA + Boolean UseSpecularAA : true + // screen space variance,Use the slider to set the strength of the geometric specular anti-aliasing effect between 0 and 1. Higher values produce a blurrier result with less aliasing. + Float SpecularAASigma + // clamping threshold,Use the slider to set a maximum value for the offset that HDRP subtracts from the smoothness value to reduce artifacts. + Float SpecularAAKappa + + //Set to true if parallax map is stored in the alpha channel of the normal map + Boolean PackedNormalParallax + + //Sets the relief height for parallax mapping + Float ParallaxHeight : 0.05 + + //Set to true to activate Steep Parallax mapping + Boolean SteepParallax + + //Horizon fade + Boolean HorizonFade + + // Set to Use Lightmap + Texture2D LightMap + + // A scalar multiplier controlling the amount of occlusion applied. + // A value of `0.0` means no occlusion. A value of `1.0` means full occlusion. + Float AoStrength + + // Set to use TexCoord2 for the lightmap sampling + Boolean SeparateTexCoord + // the light map is a grayscale ao map, only the r channel will be read. + Boolean LightMapAsAOMap + Boolean AoPackedInMRMap + //shadows + Int FilterMode + Boolean HardwareShadows + + Texture2D ShadowMap0 + Texture2D ShadowMap1 + Texture2D ShadowMap2 + Texture2D ShadowMap3 + //pointLights + Texture2D ShadowMap4 + Texture2D ShadowMap5 + + Float ShadowIntensity + Vector4 Splits + Vector2 FadeInfo + + Matrix4 LightViewProjectionMatrix0 + Matrix4 LightViewProjectionMatrix1 + Matrix4 LightViewProjectionMatrix2 + Matrix4 LightViewProjectionMatrix3 + //pointLight + Matrix4 LightViewProjectionMatrix4 + Matrix4 LightViewProjectionMatrix5 + Vector3 LightPos + Vector3 LightDir + + Float PCFEdge + Float ShadowMapSize + + // For hardware skinning + Int NumberOfBones + Matrix4Array BoneMatrices + + // For Morph animation + FloatArray MorphWeights + Int NumberOfMorphTargets + Int NumberOfTargetsBuffers + + // For instancing + Boolean UseInstancing + + // For Vertex Color + Boolean UseVertexColor + + Boolean BackfaceShadows : false + } + + Technique { + LightMode SinglePassAndImageBased + + VertexShader GLSL300 GLSL150 GLSL110: [vert] + FragmentShader GLSL300 GLSL150 GLSL110: [frag] + + WorldParameters { + WorldViewProjectionMatrix + CameraPosition + WorldMatrix + WorldNormalMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + BASECOLORMAP : BaseColorMap + NORMALMAP : NormalMap + NORMALSCALE : NormalScale + METALLICMAP : MetallicMap + ROUGHNESSMAP : RoughnessMap + EMISSIVEMAP : EmissiveMap + EMISSIVE : Emissive + SPECGLOSSPIPELINE : UseSpecGloss + PARALLAXMAP : ParallaxMap + NORMALMAP_PARALLAX : PackedNormalParallax + STEEP_PARALLAX : SteepParallax + LIGHTMAP : LightMap + SEPARATE_TEXCOORD : SeparateTexCoord + DISCARD_ALPHA : AlphaDiscardThreshold + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + USE_PACKED_MR: MetallicRoughnessMap + USE_PACKED_SG: SpecularGlossinessMap + SPECULARMAP : SpecularMap + SPECULAR_AA : UseSpecularAA + SPECULAR_AA_SCREEN_SPACE_VARIANCE : SpecularAASigma + SPECULAR_AA_THRESHOLD : SpecularAAKappa + GLOSSINESSMAP : GlossinessMap + NORMAL_TYPE: NormalType + VERTEX_COLOR : UseVertexColor + AO_MAP: LightMapAsAOMap + AO_PACKED_IN_MR_MAP : AoPackedInMRMap + AO_STRENGTH : AoStrength + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + HORIZON_FADE: HorizonFade + } + } + + + Technique PreShadow { + + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadowPBR.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + DISCARD_ALPHA : AlphaDiscardThreshold + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + ForcedRenderState { + FaceCull Off + DepthTest On + DepthWrite On + PolyOffset 5 3 + ColorWrite Off + } + + } + + + Technique PostShadow { + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowPBR.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + HARDWARE_SHADOWS : HardwareShadows + FILTER_MODE : FilterMode + PCFEDGE : PCFEdge + DISCARD_ALPHA : AlphaDiscardThreshold + SHADOWMAP_SIZE : ShadowMapSize + FADE : FadeInfo + PSSM : Splits + POINTLIGHT : LightViewProjectionMatrix5 + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + BACKFACE_SHADOWS: BackfaceShadows + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + ForcedRenderState { + Blend Modulate + DepthWrite Off + PolyOffset -0.1 0 + } + } + + Technique PreNormalPass { + + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + NormalMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + BASECOLORMAP_ALPHA : BaseColorMap + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + } + + Technique Glow { + + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/PBRGlow.frag + + WorldParameters { + WorldViewProjectionMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + HAS_EMISSIVEMAP : EmissiveMap + HAS_EMISSIVECOLOR : Emissive + BOUND_DRAW_BUFFER : BoundDrawBuffer + NEED_TEXCOORD1 + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + } + +} diff --git a/assets/Templates/pbrLightingVertex.temp b/assets/Templates/pbrLightingVertex.temp new file mode 100644 index 0000000..df5046a --- /dev/null +++ b/assets/Templates/pbrLightingVertex.temp @@ -0,0 +1,75 @@ + +#import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/Instancing.glsllib" +#import "Common/ShaderLib/Skinning.glsllib" +#import "Common/ShaderLib/MorphAnim.glsllib" + +uniform vec4 m_BaseColor; +uniform vec4 g_AmbientLightColor; +varying vec2 texCoord; + +#ifdef SEPARATE_TEXCOORD + varying vec2 texCoord2; + attribute vec2 inTexCoord2; +#endif + +varying vec4 Color; + +attribute vec3 inPosition; +attribute vec2 inTexCoord; +attribute vec3 inNormal; + +#ifdef VERTEX_COLOR + attribute vec4 inColor; +#endif + +varying vec3 wNormal; +varying vec3 wPosition; +#if defined(NORMALMAP) || defined(PARALLAXMAP) + attribute vec4 inTangent; + varying vec4 wTangent; +#endif + +void main(){ + vec4 modelSpacePos = vec4(inPosition, 1.0); + vec3 modelSpaceNorm = inNormal; + + #if ( defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING) + vec3 modelSpaceTan = inTangent.xyz; + #endif + + #ifdef NUM_MORPH_TARGETS + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + Morph_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan); + #else + Morph_Compute(modelSpacePos, modelSpaceNorm); + #endif + #endif + + #ifdef NUM_BONES + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan); + #else + Skinning_Compute(modelSpacePos, modelSpaceNorm); + #endif + #endif + + gl_Position = TransformWorldViewProjection(modelSpacePos); + texCoord = inTexCoord; + #ifdef SEPARATE_TEXCOORD + texCoord2 = inTexCoord2; + #endif + + wPosition = TransformWorld(modelSpacePos).xyz; + wNormal = TransformWorldNormal(modelSpaceNorm); + + #if defined(NORMALMAP) || defined(PARALLAXMAP) + wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); + #endif + + Color = m_BaseColor; + + #ifdef VERTEX_COLOR + Color *= inColor; + #endif +} \ No newline at end of file diff --git a/src/codex/shader/ShaderConfigApp.java b/src/codex/shader/ShaderConfigApp.java index 582acd9..a562500 100644 --- a/src/codex/shader/ShaderConfigApp.java +++ b/src/codex/shader/ShaderConfigApp.java @@ -4,7 +4,11 @@ import com.jme3.input.MouseInput; import com.jme3.input.controls.AnalogListener; import com.jme3.input.controls.MouseAxisTrigger; +import com.jme3.material.Material; import com.jme3.math.Vector3f; +import com.jme3.renderer.Camera; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; import com.simsilica.lemur.Axis; import com.simsilica.lemur.Button; @@ -29,7 +33,7 @@ * Move your Logic into AppStates or Controls * @author normenhansen */ -public class ShaderConfigApp extends SimpleApplication implements AnalogListener { +public class ShaderConfigApp extends SimpleApplication implements AnalogListener, TemplateKeyRenderer { private static final float INACTIVE = .15f; private static final float SCROLL_SPEED = 1500f; @@ -38,6 +42,7 @@ public class ShaderConfigApp extends SimpleApplication implements AnalogListener private RadioSet template; private Checkbox glslCompat; private Checkbox vertexColors; + private Checkbox alphaDiscard; private Checkbox normals, tangents; private Checkbox skinning; private Checkbox shadows; @@ -62,6 +67,8 @@ public static void main(String[] args) { ShaderConfigApp app = new ShaderConfigApp(); var settings = new AppSettings(true); settings.setTitle("JME3 Shader Wizard"); + settings.setWidth(1024); + settings.setHeight(768); app.setSettings(settings); app.start(); } @@ -92,7 +99,7 @@ public void simpleInitApp() { ); main.attachChild(template); template.setCurrentBox(0); - for (int i = 1; i < 4; i++) { + for (int i = 2; i < template.getBoxes().length; i++) { template.getBox(i).setAlpha(INACTIVE); } @@ -193,21 +200,7 @@ public void simpleInitApp() { glslVersions.add(vInput.addChild(new Checkbox("440"), 4, 3)); glslVersions.add(vInput.addChild(new Checkbox("450"), 5, 3)); - var shadersMain = main.addChild(new Container()); - shadersMain.addChild(new Label("Shader Config:", new ElementId("title.label"))); - var shadersConfig = shadersMain.addChild(new Container()); - shadersConfig.setBackground(null); - glslCompat = shadersConfig.addChild(new Checkbox("Import GLSLCompat")); - vertexColors = shadersConfig.addChild(new Checkbox("Vertex Colors")); - normals = shadersConfig.addChild(new Checkbox("Normals")); - tangents = shadersConfig.addChild(new Checkbox("Tangents")); - skinning = shadersConfig.addChild(new Checkbox("Skinning")); - instancing = shadersConfig.addChild(new Checkbox("Instancing")); - createGlowWindow(shadersConfig); - createShadowsWindow(shadersConfig); - var padding = shadersMain.addChild(new Container()); - padding.setPreferredSize(new Vector3f(20, 7, 0)); - padding.setBackground(null); + createShaderConfigWindow(main); setDefaultSettings(); @@ -223,6 +216,15 @@ public void onAnalog(String name, float value, float tpf) { } else if (name.equals("scroll-down")) { main.move(0, -tpf*SCROLL_SPEED, 0); } + } + @Override + public String makeReplacementString(String key) { + return switch (key) { + case "name" -> matDefName.getText(); + case "vert" -> getVertexExportTarget(); + case "frag" -> getFragmentExportTarget(); + default -> key; + }; } private void setDefaultSettings() { @@ -246,6 +248,28 @@ private void autocheckVersions(String... versions) { } } + private void createShaderConfigWindow(Container container) { + var window = container.addChild(new Container()); + window.addChild(new Label("Shader Config:", new ElementId("title.label"))); + var config = window.addChild(new Container()); + config.setBackground(null); + var general = config.addChild(new Container()); + general.setLayout(new SpringGridLayout(Axis.X, Axis.Y)); + general.setBackground(null); + general.setInsets(new Insets3f(0, 0, 10, 250)); + glslCompat = general.addChild(new Checkbox("Import GLSLCompat"), 0, 0); + vertexColors = general.addChild(new Checkbox("Vertex Colors"), 0, 1); + alphaDiscard = general.addChild(new Checkbox("Alpha Discard"), 0, 2); + normals = general.addChild(new Checkbox("Normals"), 0, 3); + tangents = general.addChild(new Checkbox("Tangents"), 1, 0); + skinning = general.addChild(new Checkbox("Skinning"), 1, 1); + instancing = general.addChild(new Checkbox("Instancing"), 1, 2); + createGlowWindow(config); + createShadowsWindow(config); + var padding = window.addChild(new Container()); + padding.setPreferredSize(new Vector3f(20, 7, 0)); + padding.setBackground(null); + } private void createGlowWindow(Container container) { glow = container.addChild(new Checkbox("Glow")); var glowSettings = container.addChild(new Container()); @@ -265,18 +289,18 @@ private void createShadowsWindow(Container container) { shadowSettings.setBackground(null); shadowSettings.setInsets(new Insets3f(0, 50, 0, 0)); shadowSettings.setLayout(new SpringGridLayout(Axis.Y, Axis.X)); - preShadowVert = createLabelledTextField(shadowSettings, "Pre-Shadow Vertex Shader:", "", 0, 0); + preShadowVert = createLabeledTextField(shadowSettings, "Pre-Shadow Vertex Shader:", "", 0, 0); preShadowVert.setText("Common/MatDefs/Shadow/PreShadow.vert"); - preShadowFrag = createLabelledTextField(shadowSettings, "Pre-Shadow Fragment Shader:", "", 1, 0); + preShadowFrag = createLabeledTextField(shadowSettings, "Pre-Shadow Fragment Shader:", "", 1, 0); preShadowFrag.setText("Common/MatDefs/Shadow/PreShadow.frag"); - postShadowVert = createLabelledTextField(shadowSettings, "Post-Shadow Vertex Shader:", "", 2, 0); + postShadowVert = createLabeledTextField(shadowSettings, "Post-Shadow Vertex Shader:", "", 2, 0); postShadowVert.setText("Common/MatDefs/Shadow/PostShadow.vert"); - postShadowFrag = createLabelledTextField(shadowSettings, "Post-Shadow Fragment Shader:", "", 3, 0); + postShadowFrag = createLabeledTextField(shadowSettings, "Post-Shadow Fragment Shader:", "", 3, 0); postShadowFrag.setText("Common/MatDefs/Shadow/PostShadow.frag"); //CheckboxLink.link(shadows, shadowSettings, true, INACTIVE); shadowSettings.addControl(new CheckboxFadeLink(shadows, true, INACTIVE)); } - private TextField createLabelledTextField(Container container, String name, String text, int y, int x) { + private TextField createLabeledTextField(Container container, String name, String text, int y, int x) { float paddingVertical = 3; var label = container.addChild(new Label(name, new ElementId("note.label")), y, x); label.setInsets(new Insets3f(paddingVertical, 10, paddingVertical, 5)); @@ -294,6 +318,7 @@ private boolean export() { int i = template.getCurrentIndex(); switch (i) { case 0 -> exportCustom(); + case 1 -> exportPBR(); } } catch (IOException e) { return false; @@ -311,7 +336,7 @@ private boolean verifyComplete() { } private void createSharedFolder() { if (useSharedFolder.isChecked()) { - var folder = new File(getExportPath("")); + var folder = new File(getExportPath(sharedFolderExport.getText())); if (!folder.exists()) { folder.mkdirs(); } @@ -333,23 +358,23 @@ private void exportCustom() throws IOException { } private void exportCustomMatDef() throws IOException { resetIndent(); - var file = new File(getExportPath(getMatDefExportTarget())); - if (file.exists()) { - file.delete(); - } - file.createNewFile(); - writer = new FileWriter(file); + String path = getExportPath(getMatDefExportTarget()); + System.out.println("custom matdef export: "+path); + writer = new FileWriter(createNewFile(path)); write("MaterialDef "+matDefName.getText()+" {"); indent(1); write("MaterialParameters {"); indent(1); - if (vertexColors.isChecked()) { + if (alphaDiscard.isChecked() || vertexColors.isChecked() || instancing.isChecked()) { write(""); + } + if (alphaDiscard.isChecked()) { + write("Float AlphaDiscardThreshold"); + } + if (vertexColors.isChecked()) { write("Boolean UseVertexColor"); } if (instancing.isChecked()) { - write(""); - write("// Instancing"); write("Boolean UseInstancing"); } if (skinning.isChecked()) { @@ -376,6 +401,9 @@ public void writeWorldParameters() throws IOException { } @Override public void writeDefines() throws IOException { + if (alphaDiscard.isChecked()) { + write("DISCARD_ALPHA : AlphaDiscardThreshold"); + } if (vertexColors.isChecked()) { write("VERTEX_COLOR : UseVertexColor"); } @@ -405,6 +433,9 @@ public void writeWorldParameters() throws IOException { } @Override public void writeDefines() throws IOException { + if (alphaDiscard.isChecked()) { + write("DISCARD_ALPHA : AlphaDiscardThreshold"); + } if (instancing.isChecked()) { write("INSTANCING : UseInstancing"); } @@ -432,6 +463,9 @@ public void writeWorldParameters() throws IOException { } @Override public void writeDefines() throws IOException { + if (alphaDiscard.isChecked()) { + write("DISCARD_ALPHA : AlphaDiscardThreshold"); + } if (instancing.isChecked()) { write("INSTANCING : UseInstancing"); } @@ -466,6 +500,9 @@ public void writeWorldParameters() throws IOException { } @Override public void writeDefines() throws IOException { + if (alphaDiscard.isChecked()) { + write("DISCARD_ALPHA : AlphaDiscardThreshold"); + } if (vertexColors.isChecked()) { write("VERTEX_COLOR : UseVertexColor"); } @@ -490,12 +527,7 @@ public void writeForcedRenderState() throws IOException {} } private void exportCustomVertexShader() throws IOException { resetIndent(); - var file = new File(getExportPath(getVertexExportTarget())); - if (file.exists()) { - file.delete(); - } - file.createNewFile(); - writer = new FileWriter(file); + writer = new FileWriter(createNewFile(getExportPath(getVertexExportTarget()))); write(""); if (glslCompat.isChecked()) { write("#import \"Common/ShaderLib/GLSLCompat.glsllib\""); @@ -606,8 +638,7 @@ private void exportCustomVertexShader() throws IOException { } private void exportCustomFragmentShader() throws IOException { resetIndent(); - var file = new File(getExportPath(getFragmentExportTarget())); - writer = new FileWriter(file); + writer = new FileWriter(createNewFile(getExportPath(getFragmentExportTarget()))); write(""); if (glslCompat.isChecked()) { write("#import \"Common/ShaderLib/GLSLCompat.glsllib\""); @@ -638,8 +669,24 @@ private void exportCustomFragmentShader() throws IOException { writer.close(); } - private void exportPBR() { - + private void exportPBR() throws IOException { + writer = new FileWriter(createNewFile(getExportPath(getMatDefExportTarget()))); + var matdef = (Template)assetManager.loadAsset("Templates/pbrLightingMatDef.temp"); + matdef.setKeyRenderer(this); + matdef.write(writer, ""); + writer.close(); + if (createVertShader.isChecked()) { + writer = new FileWriter(createNewFile(getExportPath(getVertexExportTarget()))); + var vertex = (Template)assetManager.loadAsset("Templates/pbrLightingVertex.temp"); + vertex.write(writer, ""); + writer.close(); + } + if (createFragShader.isChecked()) { + writer = new FileWriter(createNewFile(getExportPath(getFragmentExportTarget()))); + var fragment = (Template)assetManager.loadAsset("Templates/pbrLightingFragment.temp"); + fragment.write(writer, ""); + writer.close(); + } } private void exportPhong() { @@ -651,9 +698,9 @@ private void exportUnshaded() { private String getMatDefExportTarget() { String name = addExtension(matDefName.getText().trim(), ".j3md"); if (useSharedFolder.isChecked()) { - return name; + return trimPathSlash(combinePaths(sharedFolderExport.getText(), name)); } else { - return combinePaths(matDefExport.getText(), name); + return trimPathSlash(combinePaths(matDefExport.getText(), name)); } } private String getVertexExportTarget() { @@ -662,9 +709,9 @@ private String getVertexExportTarget() { } String name = addExtension(vertexName.getText().trim(), ".vert"); if (useSharedFolder.isChecked()) { - return name; + return trimPathSlash(combinePaths(sharedFolderExport.getText(), name)); } else { - return combinePaths(shaderExport.getText(), name); + return trimPathSlash(combinePaths(shaderExport.getText(), name)); } } private String getFragmentExportTarget() { @@ -673,18 +720,13 @@ private String getFragmentExportTarget() { } String name = addExtension(fragmentName.getText().trim(), ".frag"); if (useSharedFolder.isChecked()) { - return name; + return trimPathSlash(combinePaths(sharedFolderExport.getText(), name)); } else { - return combinePaths(shaderExport.getText(), name); + return trimPathSlash(combinePaths(shaderExport.getText(), name)); } } private String getExportPath(String ext) { - if (useSharedFolder.isChecked()) { - return combinePaths(combinePaths(assetDirectory.getText().trim(), - sharedFolderExport.getText().trim()), ext); - } else { - return combinePaths(assetDirectory.getText().trim(), ext); - } + return combinePaths(assetDirectory.getText().trim(), ext); } private String combinePaths(String path1, String path2) { boolean a = path1.endsWith("/"); @@ -698,6 +740,13 @@ private String addExtension(String path, String extension) { return path+extension; } } + private String trimPathSlash(String path) { + if (path.startsWith("/")) { + return path.substring(1); + } else { + return path; + } + } private String getSupportedGlslVersions() { String render = ""; for (var it = glslVersions.descendingIterator(); it.hasNext();) { @@ -731,4 +780,13 @@ private void writeTemplate(String asset) throws IOException { t.write(writer, indent); } + private File createNewFile(String path) throws IOException { + var file = new File(path); + if (file.exists()) { + file.delete(); + } + file.createNewFile(); + return file; + } + } diff --git a/src/codex/shader/Template.java b/src/codex/shader/Template.java index 8b7dc9f..b1a81f7 100644 --- a/src/codex/shader/Template.java +++ b/src/codex/shader/Template.java @@ -19,6 +19,7 @@ public class Template implements AssetLoader { private final LinkedList text = new LinkedList<>(); + private TemplateKeyRenderer renderer; public Template() {} @@ -26,7 +27,7 @@ public Template() {} public Template load(AssetInfo assetInfo) throws IOException { var template = new Template(); var br = new BufferedReader(new InputStreamReader(assetInfo.openStream())); - String line = null; + String line; while ((line = br.readLine()) != null) { template.text.add(line); } @@ -35,8 +36,38 @@ public Template load(AssetInfo assetInfo) throws IOException { public void write(FileWriter writer, String indent) throws IOException { for (String t : text) { + if (renderer != null) { + t = render(t); + } writer.write(indent+t+"\n"); } } + private String render(String line) { + boolean build = false; + StringBuilder render = new StringBuilder(); + StringBuilder chunk = new StringBuilder(); + for (int i = 0; i < line.length(); i++) { + char c = line.charAt(i); + if (c == '[') { + build = true; + } else if (build) { + if (c == ']') { + build = false; + String replacement = renderer.makeReplacementString(chunk.toString()); + render.append(replacement); + chunk.delete(0, chunk.length()); + } else { + chunk.append(c); + } + } else { + render.append(c); + } + } + return render.toString(); + } + + public void setKeyRenderer(TemplateKeyRenderer replacer) { + this.renderer = replacer; + } } diff --git a/src/codex/shader/TemplateKeyRenderer.java b/src/codex/shader/TemplateKeyRenderer.java new file mode 100644 index 0000000..763d576 --- /dev/null +++ b/src/codex/shader/TemplateKeyRenderer.java @@ -0,0 +1,15 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package codex.shader; + +/** + * + * @author codex + */ +public interface TemplateKeyRenderer { + + public String makeReplacementString(String key); + +}