mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	gl_rasterizer: Initial implementation of bump mapping.
This commit is contained in:
		
							parent
							
								
									449902b558
								
							
						
					
					
						commit
						9dfb223d26
					
				
					 3 changed files with 42 additions and 5 deletions
				
			
		|  | @ -702,6 +702,12 @@ struct Regs { | ||||||
|         LN = 3, // Cosine of the angle between the light and the normal vectors
 |         LN = 3, // Cosine of the angle between the light and the normal vectors
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     enum class LightingBumpMode : u32 { | ||||||
|  |         None = 0, | ||||||
|  |         NormalMap = 1, | ||||||
|  |         TangentMap = 2, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     union LightColor { |     union LightColor { | ||||||
|         BitField< 0, 10, u32> b; |         BitField< 0, 10, u32> b; | ||||||
|         BitField<10, 10, u32> g; |         BitField<10, 10, u32> g; | ||||||
|  | @ -775,7 +781,10 @@ struct Regs { | ||||||
|         union { |         union { | ||||||
|             BitField< 2, 2, LightingFresnelSelector> fresnel_selector; |             BitField< 2, 2, LightingFresnelSelector> fresnel_selector; | ||||||
|             BitField< 4, 4, LightingConfig> config; |             BitField< 4, 4, LightingConfig> config; | ||||||
|  |             BitField<22, 2, u32> bump_selector; // 0: Texture 0, 1: Texture 1, 2: Texture 2
 | ||||||
|             BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE
 |             BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE
 | ||||||
|  |             BitField<28, 2, LightingBumpMode> bump_mode; // 1: GL_TRUE, 0: GL_FALSE
 | ||||||
|  |             BitField<30, 1, u32> bump_renorm; // 0: GL_TRUE, 1: GL_FALSE
 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         union { |         union { | ||||||
|  |  | ||||||
|  | @ -119,6 +119,9 @@ struct PicaShaderConfig { | ||||||
| 
 | 
 | ||||||
|         res.lighting.config = regs.lighting.config; |         res.lighting.config = regs.lighting.config; | ||||||
|         res.lighting.fresnel_selector = regs.lighting.fresnel_selector; |         res.lighting.fresnel_selector = regs.lighting.fresnel_selector; | ||||||
|  |         res.lighting.bump_mode = regs.lighting.bump_mode; | ||||||
|  |         res.lighting.bump_selector = regs.lighting.bump_selector; | ||||||
|  |         res.lighting.bump_renorm = regs.lighting.bump_renorm == 0; | ||||||
|         res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; |         res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; | ||||||
| 
 | 
 | ||||||
|         return res; |         return res; | ||||||
|  | @ -153,6 +156,9 @@ struct PicaShaderConfig { | ||||||
| 
 | 
 | ||||||
|             bool enable = false; |             bool enable = false; | ||||||
|             unsigned src_num = 0; |             unsigned src_num = 0; | ||||||
|  |             Pica::Regs::LightingBumpMode bump_mode = Pica::Regs::LightingBumpMode::None; | ||||||
|  |             unsigned bump_selector = 0; | ||||||
|  |             bool bump_renorm = false; | ||||||
|             bool clamp_highlights = false; |             bool clamp_highlights = false; | ||||||
| 
 | 
 | ||||||
|             Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; |             Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; | ||||||
|  |  | ||||||
|  | @ -326,11 +326,28 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|            "vec3 light_vector = vec3(0.0);\n" |            "vec3 light_vector = vec3(0.0);\n" | ||||||
|            "vec3 refl_value = vec3(0.0);\n"; |            "vec3 refl_value = vec3(0.0);\n"; | ||||||
| 
 | 
 | ||||||
|     // Convert interpolated quaternion to a GL fragment normal
 |     // Compute fragment normals
 | ||||||
|     out += "vec3 normal = normalize(vec3(\n"; |     if (config.lighting.bump_mode == Pica::Regs::LightingBumpMode::NormalMap) { | ||||||
|     out += "          2.f*(normquat.x*normquat.z + normquat.y*normquat.w),\n"; |         // Bump mapping is enabled using a normal map, read perturbation vector from the selected texture
 | ||||||
|     out += "          2.f*(normquat.y*normquat.z + normquat.x*normquat.w),\n"; |         std::string bump_selector = std::to_string(config.lighting.bump_selector); | ||||||
|     out += "    1.f - 2.f*(normquat.x*normquat.x + normquat.y*normquat.y)));\n"; |         out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], texcoord[" + bump_selector + "]).rgb - 1.0;\n"; | ||||||
|  | 
 | ||||||
|  |         // Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher precision result
 | ||||||
|  |         if (config.lighting.bump_renorm) { | ||||||
|  |             std::string val = "(1.0 - (surface_normal.x*surface_normal.x + surface_normal.y*surface_normal.y))"; | ||||||
|  |             out += "surface_normal.z = sqrt(max(" + val + ", 0.0));\n"; | ||||||
|  |         } | ||||||
|  |     } else if (config.lighting.bump_mode == Pica::Regs::LightingBumpMode::TangentMap) { | ||||||
|  |         // Bump mapping is enabled using a tangent map
 | ||||||
|  |         LOG_CRITICAL(HW_GPU, "unimplemented bump mapping mode (tangent mapping)"); | ||||||
|  |         UNIMPLEMENTED(); | ||||||
|  |     } else { | ||||||
|  |         // No bump mapping - surface local normal is just a unit normal
 | ||||||
|  |         out += "vec3 surface_normal = vec3(0.0, 0.0, 1.0);\n"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Rotate the surface-local normal by the interpolated normal quaternion to convert it to eyespace
 | ||||||
|  |     out += "vec3 normal = normalize(quaternion_rotate(normquat, surface_normal));\n"; | ||||||
| 
 | 
 | ||||||
|     // Gets the index into the specified lookup table for specular lighting
 |     // Gets the index into the specified lookup table for specular lighting
 | ||||||
|     auto GetLutIndex = [config](unsigned light_num, Regs::LightingLutInput input, bool abs) { |     auto GetLutIndex = [config](unsigned light_num, Regs::LightingLutInput input, bool abs) { | ||||||
|  | @ -516,6 +533,11 @@ layout (std140) uniform shader_data { | ||||||
| uniform sampler2D tex[3]; | uniform sampler2D tex[3]; | ||||||
| uniform sampler1D lut[6]; | uniform sampler1D lut[6]; | ||||||
| 
 | 
 | ||||||
|  | // Rotate the vector v by the quaternion q
 | ||||||
|  | vec3 quaternion_rotate(vec4 q, vec3 v) { | ||||||
|  |     return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void main() { | void main() { | ||||||
| vec4 primary_fragment_color = vec4(0.0); | vec4 primary_fragment_color = vec4(0.0); | ||||||
| vec4 secondary_fragment_color = vec4(0.0); | vec4 secondary_fragment_color = vec4(0.0); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue