public void UnpackMUX( uint MUXS0, uint MUXS1, UnpackedCombiner CC_Colors) { CC_Colors.cA[0] = (uint)(MUXS0 >> 20 & 0xFL); CC_Colors.cB[0] = (uint)(MUXS1 >> 28 & 0xFL); CC_Colors.cC[0] = (uint)(MUXS0 >> 15 & 0x1FL); CC_Colors.cD[0] = (uint)(MUXS1 >> 15 & 0x7L); CC_Colors.aA[0] = (uint)(MUXS0 >> 12 & 0x7L); CC_Colors.aB[0] = (uint)(MUXS1 >> 12 & 0x7L); CC_Colors.aC[0] = (uint)(MUXS0 >> 9 & 0x7L); CC_Colors.aD[0] = (uint)(MUXS1 >> 9 & 0x7L); CC_Colors.cA[1] = (uint)(MUXS0 >> 5 & 0xFL); CC_Colors.cB[1] = (uint)(MUXS1 >> 24 & 0xFL); CC_Colors.cC[1] = (uint)(MUXS0 >> 0 & 0x1FL); CC_Colors.cD[1] = (uint)(MUXS1 >> 6 & 0x7L); CC_Colors.aA[1] = (uint)(MUXS1 >> 21 & 0x7L); CC_Colors.aB[1] = (uint)(MUXS1 >> 3 & 0x7L); CC_Colors.aC[1] = (uint)(MUXS1 >> 18 & 0x7L); CC_Colors.aD[1] = (uint)(MUXS1 >> 0 & 0x7L); }
// TODO: Lighting still seems a smidge off. // TODO: Fix shadows on cheeks, bad conversion of byte to float? // TODO: Alpha textures hide what's behind. public int CreateShaderProgram(int cycles, UnpackedCombiner combArg) { var vertexShader = this.CreateVertexShader_(); var fragmentShader = this.CreateFragmentShader_(cycles, combArg); var program = Gl.glCreateProgram(); Gl.glAttachShader(program, vertexShader); Gl.glAttachShader(program, fragmentShader); Gl.glLinkProgram(program); Gl.glGetProgramiv(program, Gl.GL_LINK_STATUS, out var linked); if (linked == Gl.GL_FALSE) { Gl.glGetProgramiv(program, Gl.GL_INFO_LOG_LENGTH, out var logSize); var logBuilder = new StringBuilder(logSize); Gl.glGetProgramInfoLog(program, logSize, out _, logBuilder); throw new Exception(Environment.NewLine + logBuilder); } return(program); }
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)); }
private DlShaderParams(UnpackedCombiner combArg) => this.CombArg = combArg;