Dynamic resolution scaling.
This commit is contained in:
parent
cf43d567f8
commit
202ad3d7cf
|
@ -32,6 +32,10 @@ uniform vec2 texStep;
|
|||
uniform float time;
|
||||
#endif
|
||||
|
||||
#ifdef _DynRes
|
||||
uniform float dynamicScale;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
#ifdef _CompoPos
|
||||
in vec3 viewRay;
|
||||
|
@ -125,10 +129,13 @@ vec3 lensflare(vec2 uv, vec2 pos) {
|
|||
|
||||
void main() {
|
||||
vec2 texCo = texCoord;
|
||||
#ifdef _DynRes
|
||||
texCo *= dynamicScale;
|
||||
#endif
|
||||
#ifdef _CompoFishEye
|
||||
const float fishEyeStrength = -0.01;
|
||||
const vec2 m = vec2(0.5, 0.5);
|
||||
vec2 d = texCoord - m;
|
||||
vec2 d = texCo - m;
|
||||
float r = sqrt(dot(d, d));
|
||||
float power = (2.0 * PI / (2.0 * sqrt(dot(m, m)))) * fishEyeStrength;
|
||||
float bind;
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
"name": "texStep",
|
||||
"link": "_screenSizeInv",
|
||||
"ifdef": ["_CompoFXAA"]
|
||||
},
|
||||
{
|
||||
"name": "dynamicScale",
|
||||
"link": "_dynamicScale",
|
||||
"ifdef": ["_DynRes"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
|
|
|
@ -9,6 +9,7 @@ class Uniforms {
|
|||
public static function register() {
|
||||
iron.object.Uniforms.externalTextureLink = externalTextureLink;
|
||||
iron.object.Uniforms.externalVec3Link = externalVec3Link;
|
||||
iron.object.Uniforms.externalFloatLink = externalFloatLink;
|
||||
}
|
||||
|
||||
public static function externalTextureLink(tulink:String):kha.Image {
|
||||
|
@ -123,4 +124,11 @@ class Uniforms {
|
|||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public static function externalFloatLink(clink:String):Float {
|
||||
if (clink == "_dynamicScale") {
|
||||
return armory.renderpath.DynamicResolutionScale.dynamicScale;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
|
51
Sources/armory/renderpath/DynamicResolutionScale.hx
Normal file
51
Sources/armory/renderpath/DynamicResolutionScale.hx
Normal file
|
@ -0,0 +1,51 @@
|
|||
package armory.renderpath;
|
||||
|
||||
import iron.data.RenderPath;
|
||||
|
||||
class DynamicResolutionScale {
|
||||
|
||||
public static var dynamicScale = 1.0;
|
||||
|
||||
static var firstFrame = true;
|
||||
static inline var startScaleMs = 30;
|
||||
static inline var scaleRangeMs = 10;
|
||||
static inline var maxScale = 0.6;
|
||||
|
||||
public static function run(path:RenderPath) {
|
||||
if (firstFrame) {
|
||||
App.notifyOnRender(render);
|
||||
firstFrame = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: execute once per frame max
|
||||
if (frameTimeAvg > startScaleMs && frameTimeAvg < 100) {
|
||||
var overTime = Math.min(scaleRangeMs, frameTimeAvg - startScaleMs);
|
||||
var scale = 1.0 - (overTime / scaleRangeMs) * (1.0 - maxScale);
|
||||
var w = Std.int(App.w() * scale);
|
||||
var h = Std.int(App.h() * scale);
|
||||
path.setCurrentViewport(w, h);
|
||||
path.setCurrentScissor(w, h);
|
||||
dynamicScale = scale;
|
||||
}
|
||||
else dynamicScale = 1.0;
|
||||
}
|
||||
|
||||
static var frameTime:Float;
|
||||
static var lastTime:Float = 0;
|
||||
static var totalTime:Float = 0;
|
||||
static var frames = 0;
|
||||
static var frameTimeAvg = 0.0;
|
||||
|
||||
public static function render(g:kha.graphics4.Graphics) {
|
||||
frameTime = kha.Scheduler.realTime() - lastTime;
|
||||
lastTime = kha.Scheduler.realTime();
|
||||
totalTime += frameTime;
|
||||
frames++;
|
||||
if (totalTime >= 1) {
|
||||
frameTimeAvg = Std.int(totalTime / frames * 10000) / 10;
|
||||
totalTime = 0;
|
||||
frames = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,10 +24,11 @@ def on_scene_update_post(context):
|
|||
# Tag redraw if playing in space_armory
|
||||
state.last_chromium_running = state.chromium_running
|
||||
state.chromium_running = False
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == 'VIEW_ARMORY':
|
||||
state.chromium_running = True
|
||||
barmory.draw()
|
||||
if not state.is_paused:
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == 'VIEW_ARMORY':
|
||||
state.chromium_running = True
|
||||
barmory.draw()
|
||||
|
||||
# Have to update chromium one more time before exit, to prevent 'AudioSyncReader::Read timed out' warnings
|
||||
if state.chromium_running == False:
|
||||
|
|
|
@ -94,6 +94,11 @@ def make_set_target(stage, node_group, node, currentNode=None, target_index=1, v
|
|||
targetId = ''
|
||||
stage['params'].append(targetId)
|
||||
|
||||
def make_set_viewport(stage, node_group, node):
|
||||
stage['command'] = 'set_viewport'
|
||||
stage['params'].append(node.inputs[1].default_value) # W
|
||||
stage['params'].append(node.inputs[2].default_value) # H
|
||||
|
||||
def make_clear_target(stage, color_val=None, depth_val=None, stencil_val=None):
|
||||
stage['command'] = 'clear_target'
|
||||
if color_val != None:
|
||||
|
@ -258,7 +263,8 @@ def make_draw_grease_pencil(stage, node_group, node):
|
|||
|
||||
def make_call_function(stage, node_group, node):
|
||||
stage['command'] = 'call_function'
|
||||
stage['params'].append(node.inputs[1].default_value)
|
||||
fstr = node.inputs[1].default_value
|
||||
stage['params'].append(fstr)
|
||||
|
||||
def make_branch_function(stage, node_group, node):
|
||||
make_call_function(stage, node_group, node)
|
||||
|
@ -446,6 +452,9 @@ def buildNode(stages, node, node_group):
|
|||
buildNode.last_bind_target = None
|
||||
make_set_target(stage, node_group, node)
|
||||
|
||||
elif node.bl_idname == 'SetViewportNodeType':
|
||||
make_set_viewport(stage, node_group, node)
|
||||
|
||||
elif node.bl_idname == 'ClearTargetNodeType':
|
||||
color_val = None
|
||||
depth_val = None
|
||||
|
@ -665,7 +674,10 @@ def get_root_node(node_group):
|
|||
break
|
||||
return rn
|
||||
|
||||
dynRes_added = False
|
||||
def preprocess_renderpath(root_node, node_group):
|
||||
global dynRes_added
|
||||
dynRes_added = False
|
||||
render_targets = []
|
||||
render_targets3D = []
|
||||
depth_buffers = []
|
||||
|
@ -701,6 +713,13 @@ def traverse_renderpath(node, node_group, render_targets, depth_buffers):
|
|||
assets.add_khafile_def('arm_vr')
|
||||
bpy.data.worlds['Arm'].world_defs += '_VR'
|
||||
|
||||
elif node.bl_idname == 'CallFunctionNodeType':
|
||||
global dynRes_added
|
||||
fstr = node.inputs[1].default_value
|
||||
if not dynRes_added and fstr.startswith('armory.renderpath.DynamicResolutionScale'):
|
||||
bpy.data.worlds['Arm'].world_defs += '_DynRes'
|
||||
dynRes_added = True
|
||||
|
||||
# Collect render targets
|
||||
if node.bl_idname == 'SetTargetNodeType' or node.bl_idname == 'BindTargetNodeType' or node.bl_idname == 'QuadPassNodeType' or node.bl_idname == 'DrawCompositorNodeType' or node.bl_idname == 'DrawCompositorWithFXAANodeType':
|
||||
if node.inputs[1].is_linked:
|
||||
|
|
|
@ -8,3 +8,4 @@ compileproc_success = False
|
|||
play_area = None
|
||||
chromium_running = False
|
||||
last_chromium_running = False
|
||||
is_paused = False
|
||||
|
|
|
@ -10,6 +10,7 @@ import make
|
|||
import make_utils
|
||||
import make_state as state
|
||||
import assets
|
||||
import log
|
||||
|
||||
# Menu in object region
|
||||
class ObjectPropsPanel(bpy.types.Panel):
|
||||
|
@ -489,6 +490,7 @@ class ArmoryPlayInViewportButton(bpy.types.Operator):
|
|||
def execute(self, context):
|
||||
assets.invalidate_enabled = False
|
||||
if state.playproc == None:
|
||||
log.clear()
|
||||
# Cancel viewport render
|
||||
for space in context.area.spaces:
|
||||
if space.type == 'VIEW_3D':
|
||||
|
|
|
@ -5,11 +5,11 @@ from bpy.app.translations import contexts as i18n_contexts
|
|||
import utils
|
||||
import make
|
||||
import make_state as state
|
||||
import log
|
||||
|
||||
class ArmorySpaceHeader(Header):
|
||||
bl_space_type = 'VIEW_ARMORY'
|
||||
info_text = ''
|
||||
is_paused = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -20,7 +20,7 @@ class ArmorySpaceHeader(Header):
|
|||
row = layout.row(align=True)
|
||||
# row.template_header()
|
||||
row.operator('arm.space_stop', icon='MESH_PLANE')
|
||||
if ArmorySpaceHeader.is_paused:
|
||||
if state.is_paused:
|
||||
row.operator('arm.space_resume', icon="PLAY")
|
||||
else:
|
||||
row.operator('arm.space_pause', icon="PAUSE")
|
||||
|
@ -37,8 +37,8 @@ class ArmorySpaceStopButton(bpy.types.Operator):
|
|||
if area == None:
|
||||
area = state.play_area
|
||||
area.type = 'VIEW_3D'
|
||||
ArmorySpaceHeader.is_paused = False
|
||||
ArmorySpaceHeader.info_text = ''
|
||||
state.is_paused = False
|
||||
log.clear()
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmorySpacePauseButton(bpy.types.Operator):
|
||||
|
@ -47,7 +47,7 @@ class ArmorySpacePauseButton(bpy.types.Operator):
|
|||
bl_label = 'Pause'
|
||||
|
||||
def execute(self, context):
|
||||
ArmorySpaceHeader.is_paused = True
|
||||
state.is_paused = True
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmorySpaceResumeButton(bpy.types.Operator):
|
||||
|
@ -56,7 +56,7 @@ class ArmorySpaceResumeButton(bpy.types.Operator):
|
|||
bl_label = 'Resume'
|
||||
|
||||
def execute(self, context):
|
||||
ArmorySpaceHeader.is_paused = False
|
||||
state.is_paused = False
|
||||
return{'FINISHED'}
|
||||
|
||||
def register():
|
||||
|
|
Loading…
Reference in a new issue