mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
ShaderGenerator: do shadow map calcs in fshader if out of varyings
If too many shadow-casting lights are active, too many TEXCOORD varyings will be used and a shader compilation error will be displayed. Instead, Panda will now just do the calculation in the fragment shader if not enough varyings are available. It's slower, but better than crashing.
This commit is contained in:
parent
dc8f01df8a
commit
0e447b7429
@ -876,20 +876,26 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
text << "\t uniform float4 mspos_view,\n";
|
||||
text << "\t out float3 l_eyevec,\n";
|
||||
}
|
||||
for (size_t i = 0; i < key._lights.size(); ++i) {
|
||||
const ShaderKey::LightInfo &light = key._lights[i];
|
||||
if (light._flags & ShaderKey::LF_has_shadows) {
|
||||
lightcoord_fregs.push_back(alloc_freg());
|
||||
text << "\t uniform float4x4 mat_shadow_" << i << ",\n";
|
||||
text << "\t out float4 l_lightcoord" << i << " : " << lightcoord_fregs[i] << ",\n";
|
||||
} else {
|
||||
lightcoord_fregs.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
if (key._fog_mode != 0) {
|
||||
hpos_freg = alloc_freg();
|
||||
text << "\t out float4 l_hpos : " << hpos_freg << ",\n";
|
||||
}
|
||||
for (size_t i = 0; i < key._lights.size(); ++i) {
|
||||
const ShaderKey::LightInfo &light = key._lights[i];
|
||||
if (light._flags & ShaderKey::LF_has_shadows) {
|
||||
if (_ftregs_used >= 8) {
|
||||
// We ran out of TEXCOORD registers. That means we have to do this
|
||||
// calculation in the fragment shader, which is slower.
|
||||
lightcoord_fregs.push_back(nullptr);
|
||||
} else {
|
||||
lightcoord_fregs.push_back(alloc_freg());
|
||||
text << "\t uniform float4x4 mat_shadow_" << i << ",\n";
|
||||
text << "\t out float4 l_lightcoord" << i << " : " << lightcoord_fregs[i] << ",\n";
|
||||
}
|
||||
} else {
|
||||
lightcoord_fregs.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
if (key._anim_spec.get_animation_type() == GeomEnums::AT_hardware &&
|
||||
key._anim_spec.get_num_transforms() > 0) {
|
||||
int num_transforms;
|
||||
@ -970,7 +976,9 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
}
|
||||
for (size_t i = 0; i < key._lights.size(); ++i) {
|
||||
if (key._lights[i]._flags & ShaderKey::LF_has_shadows) {
|
||||
text << "\t l_lightcoord" << i << " = mul(mat_shadow_" << i << ", l_eye_position);\n";
|
||||
if (lightcoord_fregs[i] != nullptr) {
|
||||
text << "\t l_lightcoord" << i << " = mul(mat_shadow_" << i << ", l_eye_position);\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key._texture_flags & ShaderKey::TF_map_height) {
|
||||
@ -1051,7 +1059,11 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
} else {
|
||||
text << "\t uniform sampler2D shadow_" << i << ",\n";
|
||||
}
|
||||
text << "\t in float4 l_lightcoord" << i << " : " << lightcoord_fregs[i] << ",\n";
|
||||
if (lightcoord_fregs[i] != nullptr) {
|
||||
text << "\t in float4 l_lightcoord" << i << " : " << lightcoord_fregs[i] << ",\n";
|
||||
} else {
|
||||
text << "\t uniform float4x4 mat_shadow_" << i << ",\n";
|
||||
}
|
||||
}
|
||||
if (light._flags & ShaderKey::LF_has_specular_color) {
|
||||
text << "\t uniform float4 attr_lspec" << i << ",\n";
|
||||
@ -1272,6 +1284,15 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
}
|
||||
for (size_t i = 0; i < key._lights.size(); ++i) {
|
||||
const ShaderKey::LightInfo &light = key._lights[i];
|
||||
|
||||
if (light._flags & ShaderKey::LF_has_shadows) {
|
||||
if (lightcoord_fregs[i] == nullptr) {
|
||||
// We have to do this one in the fragment shader if we ran out of
|
||||
// varyings.
|
||||
text << "\t float4 l_lightcoord" << i << " = mul(mat_shadow_" << i << ", float4(l_eye_position.xyz, 1.0f));\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (light._type.is_derived_from(DirectionalLight::get_class_type())) {
|
||||
text << "\t // Directional Light " << i << "\n";
|
||||
text << "\t lcolor = attr_light" << i << "[0];\n";
|
||||
|
Loading…
x
Reference in New Issue
Block a user