private static string MovC_( char letter, string target, uint value) { return($"{target} = {DlShaderGenerator.CToValue_(letter, value)};" + Environment.NewLine); }
private int CreateFragmentShader_( int cycles, UnpackedCombiner combArg) { var newLine = '\n'; // TODO: Shade might need to be an "in" instead? var fragmentHeaderLines = @"#version 400 uniform float time; uniform vec3 cameraPosition; uniform float u_lightingEnabled; uniform float u_sphericalUvEnabled; uniform float u_linearUvEnabled; struct TextureParams { vec2 clamped; vec2 mirrored; vec2 maxUv; }; uniform TextureParams textureParams0; uniform TextureParams textureParams1; uniform vec4 EnvColor; uniform vec4 PrimColor; uniform vec4 Blend; uniform float PrimColorL; uniform sampler2D texture0; uniform sampler2D texture1; in vec3 v_position; in vec2 v_uv0; in vec2 v_uv1; in vec3 v_normal; in vec3 v_projectedNormal; in vec4 v_shade; out vec4 outColor;" + newLine; fragmentHeaderLines += this.CreateUvMethods(); // TODO: Allow changing light position. var fragmentMainLines = @"vec4 applyLighting(vec4 p_color) { vec3 ambientLightColor = vec3(1, 1, 1); vec3 diffuseLightColor = vec3(1, 1, 1); vec3 specularLightColor = vec3(1, 1, 1); // Ambient color float ambientLightStrength = .2; vec3 ambientColor = ambientLightStrength * ambientLightColor; // Diffuse color vec3 normal = v_normal; //vec3 lightPos = 10000 * vec3(1, 1, 1); //vec3 lightDir = normalize(lightPos - v_position); vec3 lightDir = normalize(vec3(-1, 0, 0)); float diff = max(dot(normal, lightDir), 0); //float diff = .5 + .5 * dot(normal, lightDir); vec3 diffuseColor = diff * diffuseLightColor; // Specular color float specularStrength = 0.5; vec3 mergedColor = ambientColor + diffuseColor; vec3 finalColor = mergedColor * p_color.rgb; return vec4(finalColor, p_color.a); } vec4 calculateCcmuxColor(void) { vec3 CCRegister_0; vec3 CCRegister_1; vec3 CCReg; float ACRegister_0; float ACRegister_1; float ACReg; vec3 projectedNormal = normalize(v_projectedNormal); vec2 uv0 = calculateUv(v_uv0, textureParams0, projectedNormal); vec2 uv1 = calculateUv(v_uv1, textureParams1, projectedNormal); vec4 Texel0 = texture(texture0, uv0); vec4 Texel1 = texture(texture1, uv1);" + newLine; for (var i = 0; i < cycles; ++i) { // Final color = (ColorA [base] - ColorB) * ColorC + ColorD fragmentMainLines += DlShaderGenerator.MovC_('a', "CCRegister_0", combArg.cA[i]); fragmentMainLines += DlShaderGenerator.MovC_('b', "CCRegister_1", combArg.cB[i]); fragmentMainLines += "CCRegister_0 = CCRegister_0 - CCRegister_1;" + newLine + newLine; fragmentMainLines += DlShaderGenerator.MovC_('c', "CCRegister_1", combArg.cC[i]); fragmentMainLines += "CCRegister_0 = CCRegister_0 * CCRegister_1;" + newLine; fragmentMainLines += DlShaderGenerator.MovC_('d', "CCRegister_1", combArg.cD[i]); fragmentMainLines += "CCRegister_0 = CCRegister_0 + CCRegister_1;" + newLine + newLine; fragmentMainLines += DlShaderGenerator.MovA_('a', "ACRegister_0", combArg.aA[i]) + newLine; fragmentMainLines += DlShaderGenerator.MovA_('b', "ACRegister_1", combArg.aB[i]) + newLine; fragmentMainLines += "ACRegister_0 = ACRegister_0 - ACRegister_1;" + newLine; fragmentMainLines += DlShaderGenerator.MovA_('c', "ACRegister_1", combArg.aC[i]) + newLine; fragmentMainLines += "ACRegister_0 = ACRegister_0 * ACRegister_1;" + newLine; fragmentMainLines += DlShaderGenerator.MovA_('d', "ACRegister_1", combArg.aD[i]) + newLine; fragmentMainLines += "ACRegister_0 = ACRegister_0 + ACRegister_1;" + newLine + newLine; fragmentMainLines += @"CCReg = CCRegister_0; ACReg = ACRegister_0;" + newLine; } // TODO: Is this the right shadow calculation? fragmentMainLines += @"return vec4(CCReg, ACReg); } void main(void) { vec4 ccmuxColor = calculateCcmuxColor(); outColor = mix(ccmuxColor, applyLighting(ccmuxColor), u_lightingEnabled); }"; var fragmentShaderLines = fragmentHeaderLines + fragmentMainLines; return(ShaderCompiler.Compile(Gl.GL_FRAGMENT_SHADER, fragmentShaderLines)); }