Ver Fonte

Rework shading modes and change location of light shader

Juan Linietsky há 8 anos atrás
pai
commit
c03131fc9f

+ 2 - 0
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -3151,6 +3151,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
 	//copy reflection over diffuse, resolving SSR if needed
 	state.resolve_shader.set_conditional(ResolveShaderGLES3::USE_SSR, env->ssr_enabled);
 	state.resolve_shader.bind();
+	state.resolve_shader.set_uniform(ResolveShaderGLES3::PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+
 	glActiveTexture(GL_TEXTURE0);
 	glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
 	if (env->ssr_enabled) {

+ 4 - 0
drivers/gles3/shader_compiler_gles3.cpp

@@ -763,6 +763,10 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
 
 	actions[VS::SHADER_SPATIAL].render_mode_defines["skip_default_transform"] = "#define SKIP_TRANSFORM_USED\n";
 
+	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
+	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
+	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n";
+
 	/* PARTICLES SHADER */
 
 	actions[VS::SHADER_PARTICLES].renames["COLOR"] = "out_color";

+ 8 - 8
drivers/gles3/shader_gles3.cpp

@@ -100,14 +100,14 @@ void ShaderGLES3::bind_uniforms() {
 	};
 
 	uniforms_dirty = false;
-};
+}
 
 GLint ShaderGLES3::get_uniform_location(int p_idx) const {
 
 	ERR_FAIL_COND_V(!version, -1);
 
 	return version->uniform_location[p_idx];
-};
+}
 
 bool ShaderGLES3::bind() {
 
@@ -399,14 +399,14 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
 	strings.push_back(fragment_code2.get_data());
 
 	if (cc) {
-		code_string = cc->fragment.ascii();
+		code_string = cc->light.ascii();
 		strings.push_back(code_string.get_data());
 	}
 
 	strings.push_back(fragment_code3.get_data());
 
 	if (cc) {
-		code_string2 = cc->light.ascii();
+		code_string2 = cc->fragment.ascii();
 		strings.push_back(code_string2.get_data());
 	}
 
@@ -666,7 +666,7 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
 				//print_line("CODE1:\n"+String(fragment_code1.get_data()));
 
 				String code2 = code.substr(cpos + material_tag.length(), code.length());
-				cpos = code2.find(code_tag);
+				cpos = code2.find(light_code_tag);
 
 				if (cpos == -1) {
 					fragment_code2 = code2.ascii();
@@ -675,16 +675,16 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
 					fragment_code2 = code2.substr(0, cpos).ascii();
 					//print_line("CODE2:\n"+String(fragment_code2.get_data()));
 
-					String code3 = code2.substr(cpos + code_tag.length(), code2.length());
+					String code3 = code2.substr(cpos + light_code_tag.length(), code2.length());
 
-					cpos = code3.find(light_code_tag);
+					cpos = code3.find(code_tag);
 					if (cpos == -1) {
 						fragment_code3 = code3.ascii();
 					} else {
 
 						fragment_code3 = code3.substr(0, cpos).ascii();
 						//print_line("CODE3:\n"+String(fragment_code3.get_data()));
-						fragment_code4 = code3.substr(cpos + light_code_tag.length(), code3.length()).ascii();
+						fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii();
 						//print_line("CODE4:\n"+String(fragment_code4.get_data()));
 					}
 				}

+ 13 - 5
drivers/gles3/shaders/canvas.glsl

@@ -211,6 +211,18 @@ MATERIAL_UNIFORMS
 
 #endif
 
+
+void light_compute(inout vec3 light,vec3 light_vec,float light_height,vec4 light_color,vec2 light_uv,vec4 shadow,vec3 normal,vec2 uv,vec2 screen_uv,vec4 color) {
+
+#if defined(USE_LIGHT_SHADER_CODE)
+
+LIGHT_SHADER_CODE
+
+#endif
+
+}
+
+
 void main() {
 
 	vec4 color = color_interp;
@@ -285,11 +297,7 @@ FRAGMENT_SHADER_CODE
 
 #if defined(USE_LIGHT_SHADER_CODE)
 //light is written by the light shader
-		{
-			vec4 light_out=light*color;
-LIGHT_SHADER_CODE
-			color=light_out;
-		}
+		light_compute(light,light_vec,light_height,light_color,light_uv,shadow,normal,uv,screen_uv,color);
 
 #else
 

+ 4 - 0
drivers/gles3/shaders/particles.glsl

@@ -243,6 +243,10 @@ MATERIAL_UNIFORMS
 
 void main() {
 
+	{
+LIGHT_SHADER_CODE
+	}
+
 	{
 FRAGMENT_SHADER_CODE
 	}

+ 1 - 1
drivers/gles3/shaders/resolve.glsl

@@ -20,7 +20,7 @@ in vec2 uv_interp;
 uniform sampler2D source_specular; //texunit:0
 uniform sampler2D source_ssr; //texunit:1
 
-uniform float stuff;
+uniform vec2 pixel_size;
 
 in vec2 uv2_interp;
 

+ 55 - 10
drivers/gles3/shaders/scene.glsl

@@ -623,15 +623,66 @@ float GTR1(float NdotH, float a)
 
 void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color,  float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
 
+#if defined(USE_LIGHT_SHADER_CODE)
+//light is written by the light shader
+
+
+LIGHT_SHADER_CODE
+
+
+#else
+
 	float dotNL = max(dot(N,L), 0.0 );
-	float dotNV = max(dot(N,V), 0.0 );
 
+#if defined(DIFFUSE_HALF_LAMBERT)
+
+	float hl = dot(N,L) * 0.5 + 0.5;
+	diffuse += hl * light_color * diffuse_color;
+
+#elif defined(DIFFUSE_OREN_NAYAR)
+
+	{
+		float LdotV = dot(L, V);
+		float NdotL = dot(L, N);
+		float NdotV = dot(N, V);
+
+		float s = LdotV - NdotL * NdotV;
+		float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
+
+		float sigma2 = roughness * roughness;
+		vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33));
+		float B = 0.45 * sigma2 / (sigma2 + 0.09);
+
+		diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
+	}
+
+#elif defined(DIFFUSE_BURLEY)
+
+	{
+		float NdotL = dot(L, N);
+		float NdotV = dot(N, V);
+		float VdotH = dot(N, normalize(L+V));
+		float energyBias = mix(roughness, 0.0, 0.5);
+		float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
+		float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness;
+		float f0 = 1.0;
+		float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0);
+		float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0);
+
+		diffuse+= light_color * diffuse_color * lightScatter * viewScatter * energyFactor;
+	}
+#else
+
+	diffuse += dotNL * light_color * diffuse_color;
+#endif
+
+
+	float dotNV = max(dot(N,V), 0.0 );
 #if defined(LIGHT_USE_RIM)
 	float rim_light = pow(1.0-dotNV,(1.0-roughness)*16.0);
 	diffuse += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
 #endif
 
-	diffuse += dotNL * light_color * diffuse_color;
 
 	if (roughness > 0.0) {
 
@@ -685,6 +736,7 @@ void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 di
 	}
 
 
+#endif //defined(USE_LIGHT_SHADER_CODE)
 }
 
 
@@ -1507,14 +1559,7 @@ FRAGMENT_SHADER_CODE
 
 
 
-#if defined(USE_LIGHT_SHADER_CODE)
-//light is written by the light shader
-{
 
-LIGHT_SHADER_CODE
-
-}
-#endif
 
 #ifdef RENDER_DEPTH
 //nothing happens, so a tree-ssa optimizer will result in no fragment shader :)
@@ -1566,7 +1611,7 @@ LIGHT_SHADER_CODE
 #endif //ENABLE_AO
 
 	diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale);
-	specular_buffer=vec4(specular_light,max(specular.r,max(specular.g,specular.b)));
+	specular_buffer=vec4(specular_light,metallic);
 
 
 	normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);

+ 7 - 1
scene/resources/material.cpp

@@ -278,6 +278,12 @@ void SpatialMaterial::_update_shader() {
 		case CULL_FRONT: code += ",cull_front"; break;
 		case CULL_DISABLED: code += ",cull_disabled"; break;
 	}
+	switch (diffuse_mode) {
+		case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break;
+		case DIFFUSE_HALF_LAMBERT: code += ",diffuse_half_lambert"; break;
+		case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break;
+		case DIFFUSE_BURLEY: code += ",diffuse_burley"; break;
+	}
 
 	if (flags[FLAG_UNSHADED]) {
 		code += ",unshaded";
@@ -1248,7 +1254,7 @@ void SpatialMaterial::_bind_methods() {
 	BIND_CONSTANT(FLAG_MAX);
 
 	BIND_CONSTANT(DIFFUSE_LAMBERT);
-	BIND_CONSTANT(DIFFUSE_LAMBERT_WRAP);
+	BIND_CONSTANT(DIFFUSE_HALF_LAMBERT);
 	BIND_CONSTANT(DIFFUSE_OREN_NAYAR);
 	BIND_CONSTANT(DIFFUSE_BURLEY);
 

+ 1 - 1
scene/resources/material.h

@@ -160,7 +160,7 @@ public:
 
 	enum DiffuseMode {
 		DIFFUSE_LAMBERT,
-		DIFFUSE_LAMBERT_WRAP,
+		DIFFUSE_HALF_LAMBERT,
 		DIFFUSE_OREN_NAYAR,
 		DIFFUSE_BURLEY,
 	};

+ 5 - 2
servers/visual/shader_types.cpp

@@ -131,6 +131,11 @@ ShaderTypes::ShaderTypes() {
 	shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
 	shader_modes[VS::SHADER_SPATIAL].modes.insert("ontop");
 
+	shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert");
+	shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_half_lambert");
+	shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar");
+	shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley");
+
 	shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_default_transform");
 
 	/************ CANVAS ITEM **************************/
@@ -166,8 +171,6 @@ ShaderTypes::ShaderTypes() {
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
-	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["VAR1"] = ShaderLanguage::TYPE_VEC4;
-	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["VAR2"] = ShaderLanguage::TYPE_VEC4;
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;