mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
-multiSun commandline flag: Draw sun/skylights only if they come from the sky whose shader they were defined in.
Every shader that emits sun or skyligghts gets an environment emitter index. All the suns/lights generated from that shader get the same index. trace_t now has a bitmask of all the environment emitter indices encountered when hitting sky surfaces and checking their shader. Lighting code checks whether the current sunlight has a defined environment emitter index and if it does, it checks whether it is set in the bitmask. Only then will the light be considered to hit.
This commit is contained in:
@@ -260,6 +260,7 @@ td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
|
||||
<li><strong><code>-lomem</code>:</strong> Low memory but slower lighting mode</li>
|
||||
<li><strong><code>-lowquality</code>:</strong> Low quality floodlight (appears to currently break floodlight)</li>
|
||||
<li><strong><code>-minsamplesize</code> N:</strong> Sets minimum lightmap resolution in luxels/qu</li>
|
||||
<li><strong><code>-multiSun</code> N:</strong> Restrict sun and skylights to being emitted from surfaces carrying the shader they were defined in (as opposed to globally)</li>
|
||||
<li><strong><code>-nobouncestore</code>:</strong> Do not store BSP, lightmap and shader files between bounces</li>
|
||||
<li><strong><code>-nocollapse</code>:</strong> Do not collapse identical lightmaps</li>
|
||||
<li><strong><code>-nodeluxe</code>, <code>-nodeluxemap</code>:</strong> Disable deluxemapping</li>
|
||||
|
||||
@@ -401,6 +401,11 @@ textures/eerie/ironcrosslt2_10000
|
||||
<dt>sample_color</dt><dd>Default = 1: sample color of each individual light from skybox images, if they are present. 0: use shader color, set by <a href="q3map-global-directives.html#q3map_lightRGB">q3map_lightRGB</a>/<a href="q3map-global-directives.html#q3map_lightImage">q3map_lightImage</a>/<a href="general-directives.html#skyParms">_up skybox image</a>/<a href="quake-editor-radiant-directives.html#qer_editorImage">qer_editorImage</a>.</dd>
|
||||
</dl>
|
||||
|
||||
<blockquote>
|
||||
<h4>Design Notes:</h4>
|
||||
<p>Normally, all suns and skylights are emitted from all sky surfaces in a map. If you wish to restrict them to being emitted from surfaces carrying the exact shader that defined them, e.g. to have different sun/sky lighting in different areas of the map, compile your map with the -multiSun keyword in the light stage.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="q3map_splotchFix">q3map_splotchFix</h2>
|
||||
<p>This is used on lightmapped model shaders if splotched lighting artifacts appear. Any shadows at the ambient/dark level will be flooded from neighbouring luxels. This gets rid of shadow acne, but a surface must be more or less uniformly lit or this looks ugly. Try using <a href="q3map-global-directives.html#q3map_lightmapSampleOffset">q3map_lightmapSampleOffset</a> first before using this as a last resort.</p>
|
||||
|
||||
@@ -428,6 +433,8 @@ textures/eerie/ironcrosslt2_10000
|
||||
<p>Sky shaders should probably still have a <a href="q3map-global-directives.html#q3map_surfaceLight">q3map_surfaceLight</a> or preferred <a href="q3map-global-directives.html#q3map_skylight">q3map_skylight</a> value. The "sun" gives a strong directional light, but doesn't necessarily give the fill light needed to soften and illuminate shadows. Skies with clouds should probably have a weaker <a href="q3map-global-directives.html#q3map_sun">q3map_sun</a> value and a higher <a href="q3map-global-directives.html#q3map_surfaceLight">q3map_surfaceLight</a> or <a href="q3map-global-directives.html#q3map_skylight">q3map_skylight</a> value. Heavy clouds diffuse light and weaken shadows. The opposite is true of a cloudless or nearly cloudless sky. In such cases, the "sun" or "moon" will cast stronger shadows that have a greater degree of contrast. This is also why q3map_sunExt is preferred. It gives the designer greater control over shadow contrast with a penumbra effect.</p>
|
||||
<h4>Design Notes:</h4>
|
||||
<p>Not certain what color formula you want to use for the sun's light? Try this. Create a light entity. Use the Radiant editor's color selection tools to pick a color. The light's _color key's value will be the normalized RGB formula. Copy it from the value line in the editor (CTRL+c) and paste it into your shader.</p>
|
||||
<h4>Design Notes:</h4>
|
||||
<p>Normally, all suns and skylights are emitted from all sky surfaces in a map. If you wish to restrict them to being emitted from surfaces carrying the exact shader that defined them, e.g. to have different sun/sky lighting in different areas of the map, compile your map with the -multiSun keyword in the light stage.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="q3map_surfaceLight">q3map_surfaceLight value</h2>
|
||||
|
||||
@@ -226,6 +226,7 @@ static void HelpLight()
|
||||
{ "-lomem", "Low memory but slower lighting mode" },
|
||||
{ "-lowquality", "Low quality floodlight (appears to currently break floodlight)" },
|
||||
{ "-minsamplesize <N>", "Sets minimum lightmap resolution in luxels/qu" },
|
||||
{ "-multisun", "Restrict sun and skylights to being emitted from surfaces carrying the shader they were defined in (as opposed to globally)" },
|
||||
{ "-nobouncestore", "Do not store BSP, lightmap and shader files between bounces" },
|
||||
{ "-nocollapse", "Do not collapse identical lightmaps" },
|
||||
{ "-nodeluxe, -nodeluxemap", "Disable deluxemapping" },
|
||||
|
||||
@@ -100,6 +100,7 @@ static void CreateSunLight( sun_t& sun ){
|
||||
light.falloffTolerance = falloffTolerance;
|
||||
light.filterRadius = sun.filterRadius / sun.numSamples;
|
||||
light.style = noStyles ? LS_NORMAL : sun.style;
|
||||
light.environmentLightIndex = sun.environmentLightIndex;
|
||||
|
||||
/* set the light's position out to infinity */
|
||||
light.origin = direction * ( MAX_WORLD_COORD * 8.0f ); /* MAX_WORLD_COORD * 2.0f */
|
||||
@@ -234,6 +235,7 @@ static void CreateSkyLights( const skylight_t& skylight, const Vector3& color, f
|
||||
sun.deviance = 0.0f;
|
||||
sun.filterRadius = filterRadius;
|
||||
sun.numSamples = 1;
|
||||
sun.environmentLightIndex = skylight.environmentLightIndex;
|
||||
sun.style = noStyles ? LS_NORMAL : style;
|
||||
|
||||
/* setup */
|
||||
@@ -599,6 +601,16 @@ static void CreateSurfaceLights(){
|
||||
if ( !si->suns.empty() && !nss ) {
|
||||
auto* si_ = const_cast<shaderInfo_t*>( si ); /* FIXME: hack! */
|
||||
Sys_FPrintf( SYS_VRB, "Sun: %s\n", si->shader.c_str() );
|
||||
if(multiSun){
|
||||
if(si->environmentEmitterIndex == -1){
|
||||
// this shader is actually emitting sun/skylight now, so give it an environment emitter index
|
||||
si_->environmentEmitterIndex = nextEnvironmentLightIndex++;
|
||||
}
|
||||
// let the suns know
|
||||
for( auto sunIt = si_->suns.begin(); sunIt != si_->suns.end(); sunIt++ ){
|
||||
sunIt->environmentLightIndex = si_->environmentEmitterIndex;
|
||||
}
|
||||
}
|
||||
std::ranges::for_each( si_->suns, CreateSunLight );
|
||||
si_->suns.clear(); /* FIXME: hack! */
|
||||
}
|
||||
@@ -606,6 +618,17 @@ static void CreateSurfaceLights(){
|
||||
/* sky light? */
|
||||
if ( !si->skylights.empty() ) {
|
||||
Sys_FPrintf( SYS_VRB, "Sky: %s\n", si->shader.c_str() );
|
||||
if(multiSun){
|
||||
shaderInfo_t* si_ = const_cast<shaderInfo_t*>( si ); /* FIXME: hack! */
|
||||
if(si->environmentEmitterIndex == -1){
|
||||
// this shader is actually emitting sun/skylight now, so give it an environment emitter index
|
||||
si_->environmentEmitterIndex = nextEnvironmentLightIndex++;
|
||||
}
|
||||
// let the skies know
|
||||
for( auto skyIt = si_->skylights.begin(); skyIt != si_->skylights.end(); skyIt++ ){
|
||||
skyIt->environmentLightIndex = si_->environmentEmitterIndex;
|
||||
}
|
||||
}
|
||||
for( const skylight_t& skylight : si->skylights )
|
||||
CreateSkyLights( skylight, si->color, si->lightFilterRadius, si->lightStyle, si->skyParmsImageBase );
|
||||
const_cast<shaderInfo_t*>( si )->skylights.clear(); /* FIXME: hack! */
|
||||
@@ -1098,7 +1121,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
/* trace */
|
||||
TraceLine( trace );
|
||||
trace->forceSubsampling *= add;
|
||||
if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) {
|
||||
if ( !( trace->compileFlags & C_SKY ) || trace->opaque || multiSun && light->environmentLightIndex != -1 && light->environmentLightIndex < MULTISUN_MAX && !bit_is_enabled(trace->skyEnvironmentLightIndices,light->environmentLightIndex) ) {
|
||||
trace->color.set( 0 );
|
||||
trace->directionContribution.set( 0 );
|
||||
|
||||
@@ -1394,7 +1417,7 @@ static bool LightContributionToPoint( trace_t *trace ){
|
||||
if ( trace->testOcclusion && !trace->forceSunlight ) {
|
||||
/* trace */
|
||||
TraceLine( trace );
|
||||
if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) {
|
||||
if ( !( trace->compileFlags & C_SKY ) || trace->opaque || multiSun && light->environmentLightIndex != -1 && light->environmentLightIndex < MULTISUN_MAX && !bit_is_enabled(trace->skyEnvironmentLightIndices,light->environmentLightIndex) ) {
|
||||
trace->color.set( 0 );
|
||||
return false;
|
||||
}
|
||||
@@ -2496,6 +2519,10 @@ int LightMain( Args& args ){
|
||||
Sys_Printf( "Approximating lightmaps within a byte tolerance of %d\n", approximateTolerance );
|
||||
}
|
||||
}
|
||||
while ( args.takeArg( "-multisun" ) ) {
|
||||
multiSun = true;
|
||||
Sys_Printf( "Multi-sun support activated\n" );
|
||||
}
|
||||
while ( args.takeArg( "-deluxe", "-deluxemap" ) ) {
|
||||
deluxemap = true;
|
||||
Sys_Printf( "Generating deluxemaps for average light direction\n" );
|
||||
|
||||
@@ -1351,6 +1351,9 @@ static bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace
|
||||
|
||||
/* don't trace against sky */
|
||||
if ( si->compileFlags & C_SKY ) {
|
||||
if(multiSun && trace->light && trace->light->environmentLightIndex != -1 && si->environmentEmitterIndex != -1 && si->environmentEmitterIndex < MULTISUN_MAX){
|
||||
bit_enable(trace->skyEnvironmentLightIndices,si->environmentEmitterIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1597,6 +1600,9 @@ void TraceLine( trace_t *trace ){
|
||||
trace->passSolid = false;
|
||||
trace->opaque = false;
|
||||
trace->compileFlags = 0;
|
||||
if(multiSun){
|
||||
memset(trace->skyEnvironmentLightIndices,0,sizeof(trace->skyEnvironmentLightIndices));
|
||||
}
|
||||
trace->numTestNodes = 0;
|
||||
|
||||
/* early outs */
|
||||
|
||||
@@ -155,6 +155,9 @@ enum class EBrushType
|
||||
|
||||
|
||||
/* light */
|
||||
#define MULTISUN_MAX 2048 // TA: multi sun. this is how many separate suns can be drawn separately and only where they should
|
||||
#define MULTISUN_MAX_BYTES (MULTISUN_MAX/8) // it's a bitmask. 256 bytes in the end.
|
||||
|
||||
#define MAX_TRACE_TEST_NODES 256
|
||||
#define DEFAULT_INHIBIT_RADIUS 1.5f
|
||||
|
||||
@@ -414,6 +417,7 @@ struct sun_t
|
||||
Vector3 direction, color;
|
||||
float photons, deviance, filterRadius;
|
||||
int numSamples, style;
|
||||
int environmentLightIndex = -1;
|
||||
};
|
||||
|
||||
struct skylight_t
|
||||
@@ -423,6 +427,7 @@ struct skylight_t
|
||||
int horizon_min = 0;
|
||||
int horizon_max = 90;
|
||||
bool sample_color = true;
|
||||
int environmentLightIndex = -1;
|
||||
};
|
||||
|
||||
|
||||
@@ -579,6 +584,7 @@ struct shaderInfo_t_data
|
||||
|
||||
std::vector<skylight_t> skylights; /* ydnar */
|
||||
std::vector<sun_t> suns; /* ydnar */
|
||||
int environmentEmitterIndex = -1; /* TA: multisun: shaders that end up being used and actually emit sunlight get a unique emitter index */
|
||||
|
||||
Vector3 color{ 0 }; /* normalized color */
|
||||
Color4f averageColor = { 0, 0, 0, 0 };
|
||||
@@ -1083,6 +1089,8 @@ struct light_t
|
||||
|
||||
float falloffTolerance; /* ydnar: minimum attenuation threshold */
|
||||
float filterRadius; /* ydnar: lightmap filter radius in world units, 0 == default */
|
||||
|
||||
int environmentLightIndex = -1; /* TA: For sun/skylights. Check if particular sky triangle emits a given light */
|
||||
};
|
||||
|
||||
|
||||
@@ -1106,9 +1114,12 @@ struct trace_t
|
||||
float inhibitRadius; /* sphere in which occluding geometry is ignored */
|
||||
|
||||
/* per-light input */
|
||||
const light_t *light;
|
||||
const light_t *light = nullptr;
|
||||
Vector3 end;
|
||||
|
||||
/* TA: multisun support */
|
||||
byte skyEnvironmentLightIndices[MULTISUN_MAX_BYTES];
|
||||
|
||||
/* calculated input */
|
||||
Vector3 displacement, direction;
|
||||
float distance;
|
||||
@@ -2026,6 +2037,10 @@ inline const bool exactPointToPolygon = true;
|
||||
inline const float formFactorValueScale = 3.0f;
|
||||
inline const float linearScale = 1.0f / 8000.0f;
|
||||
|
||||
/* TA: multisun stuff (ability to have mutliple skyboxes with separate suns/skylights). May not handle _skybox properly */
|
||||
inline bool multiSun = false;
|
||||
inline int nextEnvironmentLightIndex = 0; // each shader environment light (sun/sky) gets a unique index. thus we can check whether a sky surface should be considered as a successful trace
|
||||
|
||||
inline std::list<light_t> lights;
|
||||
inline int numPointLights;
|
||||
inline int numSpotLights;
|
||||
|
||||
Reference in New Issue
Block a user