mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Add Cone and Cylinder shapes to FogVolume
This complements the existing Ellipsoid and Box local fog shapes. This can be used to represent a light cone coming from a SpotLight.
This commit is contained in:
parent
1c99b7415f
commit
e85459dcd1
@ -11,14 +11,15 @@
|
||||
</tutorials>
|
||||
<members>
|
||||
<member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3(1, 1, 1)">
|
||||
Sets the size of the [FogVolume] when [member shape] is [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID] or [constant RenderingServer.FOG_VOLUME_SHAPE_BOX].
|
||||
Sets the size of the [FogVolume] when [member shape] is [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID], [constant RenderingServer.FOG_VOLUME_SHAPE_CONE], [constant RenderingServer.FOG_VOLUME_SHAPE_CYLINDER] or [constant RenderingServer.FOG_VOLUME_SHAPE_BOX].
|
||||
[b]Note:[/b] Thin fog volumes may appear to flicker when the camera moves or rotates. This can be alleviated by increasing [member ProjectSettings.rendering/environment/volumetric_fog/volume_depth] (at a performance cost) or by decreasing [member Environment.volumetric_fog_length] (at no performance cost, but at the cost of lower fog range). Alternatively, the [FogVolume] can be made thicker and use a lower density in the [member material].
|
||||
[b]Note:[/b] If [member shape] is [constant RenderingServer.FOG_VOLUME_SHAPE_CONE] or [constant RenderingServer.FOG_VOLUME_SHAPE_CYLINDER], the cone/cylinder will be adjusted to fit within the extents. Non-uniform scaling of cone/cylinder shapes via the [member extents] property is not supported, but you can scale the [FogVolume] node instead.
|
||||
</member>
|
||||
<member name="material" type="Material" setter="set_material" getter="get_material">
|
||||
Sets the [Material] to be used by the [FogVolume]. Can be either a [FogMaterial] or a custom [ShaderMaterial].
|
||||
</member>
|
||||
<member name="shape" type="int" setter="set_shape" getter="get_shape" enum="RenderingServer.FogVolumeShape" default="1">
|
||||
Sets the shape of the [FogVolume] to either [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID], [constant RenderingServer.FOG_VOLUME_SHAPE_BOX], or [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID] or [constant RenderingServer.FOG_VOLUME_SHAPE_WORLD].
|
||||
<member name="shape" type="int" setter="set_shape" getter="get_shape" enum="RenderingServer.FogVolumeShape" default="3">
|
||||
Sets the shape of the [FogVolume] to either [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID], [constant RenderingServer.FOG_VOLUME_SHAPE_CONE], [constant RenderingServer.FOG_VOLUME_SHAPE_CYLINDER], [constant RenderingServer.FOG_VOLUME_SHAPE_BOX] or [constant RenderingServer.FOG_VOLUME_SHAPE_WORLD].
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
@ -1186,7 +1186,7 @@
|
||||
<argument index="0" name="fog_volume" type="RID" />
|
||||
<argument index="1" name="extents" type="Vector3" />
|
||||
<description>
|
||||
Sets the size of the fog volume when shape is [constant FOG_VOLUME_SHAPE_ELLIPSOID] or [constant FOG_VOLUME_SHAPE_BOX].
|
||||
Sets the size of the fog volume when shape is [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID], [constant RenderingServer.FOG_VOLUME_SHAPE_CONE], [constant RenderingServer.FOG_VOLUME_SHAPE_CYLINDER] or [constant RenderingServer.FOG_VOLUME_SHAPE_BOX].
|
||||
</description>
|
||||
</method>
|
||||
<method name="fog_volume_set_material">
|
||||
@ -1202,7 +1202,7 @@
|
||||
<argument index="0" name="fog_volume" type="RID" />
|
||||
<argument index="1" name="shape" type="int" enum="RenderingServer.FogVolumeShape" />
|
||||
<description>
|
||||
Sets the shape of the fog volume to either [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID], [constant RenderingServer.FOG_VOLUME_SHAPE_BOX], or [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID] or [constant RenderingServer.FOG_VOLUME_SHAPE_WORLD].
|
||||
Sets the shape of the fog volume to either [constant RenderingServer.FOG_VOLUME_SHAPE_ELLIPSOID], [constant RenderingServer.FOG_VOLUME_SHAPE_CONE], [constant RenderingServer.FOG_VOLUME_SHAPE_CYLINDER], [constant RenderingServer.FOG_VOLUME_SHAPE_BOX] or [constant RenderingServer.FOG_VOLUME_SHAPE_WORLD].
|
||||
</description>
|
||||
</method>
|
||||
<method name="force_draw">
|
||||
@ -3931,14 +3931,22 @@
|
||||
<constant name="PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX" value="6" enum="ParticlesCollisionHeightfieldResolution">
|
||||
</constant>
|
||||
<constant name="FOG_VOLUME_SHAPE_ELLIPSOID" value="0" enum="FogVolumeShape">
|
||||
[FogVolume] will be shaped like an ellipsoid.
|
||||
[FogVolume] will be shaped like an ellipsoid (stretched sphere).
|
||||
</constant>
|
||||
<constant name="FOG_VOLUME_SHAPE_BOX" value="1" enum="FogVolumeShape">
|
||||
<constant name="FOG_VOLUME_SHAPE_CONE" value="1" enum="FogVolumeShape">
|
||||
[FogVolume] will be shaped like a cone pointing upwards (in local coordinates). The cone's angle is set automatically to fill the extents. The cone will be adjusted to fit within the extents. Rotate the [FogVolume] node to reorient the cone. Non-uniform scaling via extents is not supported (scale the [FogVolume] node instead).
|
||||
</constant>
|
||||
<constant name="FOG_VOLUME_SHAPE_CYLINDER" value="2" enum="FogVolumeShape">
|
||||
[FogVolume] will be shaped like an upright cylinder (in local coordinates). Rotate the [FogVolume] node to reorient the cylinder. The cylinder will be adjusted to fit within the extents. Non-uniform scaling via extents is not supported (scale the [FogVolume] node instead).
|
||||
</constant>
|
||||
<constant name="FOG_VOLUME_SHAPE_BOX" value="3" enum="FogVolumeShape">
|
||||
[FogVolume] will be shaped like a box.
|
||||
</constant>
|
||||
<constant name="FOG_VOLUME_SHAPE_WORLD" value="2" enum="FogVolumeShape">
|
||||
<constant name="FOG_VOLUME_SHAPE_WORLD" value="4" enum="FogVolumeShape">
|
||||
[FogVolume] will have no shape, will cover the whole world and will not be culled.
|
||||
</constant>
|
||||
<constant name="FOG_VOLUME_SHAPE_MAX" value="5" enum="FogVolumeShape">
|
||||
</constant>
|
||||
<constant name="VIEWPORT_SCALING_3D_MODE_BILINEAR" value="0" enum="ViewportScaling3DMode">
|
||||
Use bilinear scaling for the viewport's 3D buffer. The amount of scaling can be set using [member Viewport.scaling_3d_scale]. Values less then [code]1.0[/code] will result in undersampling while values greater than [code]1.0[/code] will result in supersampling. A value of [code]1.0[/code] disables scaling.
|
||||
</constant>
|
||||
|
@ -41,7 +41,7 @@ void FogVolume::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_material"), &FogVolume::get_material);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shape", PROPERTY_HINT_ENUM, "Ellipsoid,Box,World"), "set_shape", "get_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shape", PROPERTY_HINT_ENUM, "Ellipsoid (Local),Cone (Local),Cylinder (Local),Box (Local),World (Global)"), "set_shape", "get_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "FogMaterial,ShaderMaterial"), "set_material", "get_material");
|
||||
}
|
||||
|
||||
|
@ -4365,7 +4365,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
|
||||
RS::FogVolumeShape volume_type = storage->fog_volume_get_shape(fog_volume);
|
||||
Vector3 extents = storage->fog_volume_get_extents(fog_volume);
|
||||
|
||||
if (volume_type == RS::FOG_VOLUME_SHAPE_BOX || volume_type == RS::FOG_VOLUME_SHAPE_ELLIPSOID) {
|
||||
if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
|
||||
// Local fog volume.
|
||||
Vector3i points[8];
|
||||
points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform);
|
||||
points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform);
|
||||
|
@ -97,6 +97,8 @@ AABB RendererStorageRD::fog_volume_get_aabb(RID p_fog_volume) const {
|
||||
|
||||
switch (fog_volume->shape) {
|
||||
case RS::FOG_VOLUME_SHAPE_ELLIPSOID:
|
||||
case RS::FOG_VOLUME_SHAPE_CONE:
|
||||
case RS::FOG_VOLUME_SHAPE_CYLINDER:
|
||||
case RS::FOG_VOLUME_SHAPE_BOX: {
|
||||
AABB aabb;
|
||||
aabb.position = -fog_volume->extents;
|
||||
|
@ -186,12 +186,31 @@ void main() {
|
||||
|
||||
float sdf = -1.0;
|
||||
if (params.shape == 0) {
|
||||
//Ellipsoid
|
||||
// Ellipsoid
|
||||
// https://www.shadertoy.com/view/tdS3DG
|
||||
float k0 = length(local_pos.xyz / params.extents);
|
||||
float k1 = length(local_pos.xyz / (params.extents * params.extents));
|
||||
sdf = k0 * (k0 - 1.0) / k1;
|
||||
} else if (params.shape == 1) {
|
||||
// Cone
|
||||
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
|
||||
// Compute the cone angle automatically to fit within the volume's extents.
|
||||
float inv_height = 1.0 / max(0.001, params.extents.y);
|
||||
float radius = 1.0 / max(0.001, (min(params.extents.x, params.extents.z) * 0.5));
|
||||
float hypotenuse = sqrt(radius * radius + inv_height * inv_height);
|
||||
float rsin = radius / hypotenuse;
|
||||
float rcos = inv_height / hypotenuse;
|
||||
vec2 c = vec2(rsin, rcos);
|
||||
|
||||
float q = length(local_pos.xz);
|
||||
sdf = max(dot(c, vec2(q, local_pos.y - params.extents.y)), -params.extents.y - local_pos.y);
|
||||
} else if (params.shape == 2) {
|
||||
// Cylinder
|
||||
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
vec2 d = abs(vec2(length(local_pos.xz), local_pos.y)) - vec2(min(params.extents.x, params.extents.z), params.extents.y);
|
||||
sdf = min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
|
||||
} else if (params.shape == 3) {
|
||||
// Box
|
||||
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
vec3 q = abs(local_pos.xyz) - params.extents;
|
||||
@ -199,7 +218,7 @@ void main() {
|
||||
}
|
||||
|
||||
float cull_mask = 1.0; //used to cull cells that do not contribute
|
||||
if (params.shape <= 1) {
|
||||
if (params.shape <= 3) {
|
||||
#ifndef SDF_USED
|
||||
cull_mask = 1.0 - smoothstep(-0.1, 0.0, sdf);
|
||||
#endif
|
||||
|
@ -2140,8 +2140,11 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("fog_volume_set_material", "fog_volume", "material"), &RenderingServer::fog_volume_set_material);
|
||||
|
||||
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_ELLIPSOID);
|
||||
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_CONE);
|
||||
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_CYLINDER);
|
||||
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_BOX);
|
||||
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_WORLD);
|
||||
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_MAX);
|
||||
|
||||
/* VISIBILITY NOTIFIER */
|
||||
|
||||
|
@ -724,8 +724,11 @@ public:
|
||||
|
||||
enum FogVolumeShape {
|
||||
FOG_VOLUME_SHAPE_ELLIPSOID,
|
||||
FOG_VOLUME_SHAPE_CONE,
|
||||
FOG_VOLUME_SHAPE_CYLINDER,
|
||||
FOG_VOLUME_SHAPE_BOX,
|
||||
FOG_VOLUME_SHAPE_WORLD,
|
||||
FOG_VOLUME_SHAPE_MAX,
|
||||
};
|
||||
|
||||
virtual void fog_volume_set_shape(RID p_fog_volume, FogVolumeShape p_shape) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user