• Understanding Random Forest using Python (scikit-learn)

    Decision trees are a popular supervised learning algorithm with benefits that include being able to be used for both regression and classification as well as being easy to interpret. However, decision trees aren’t the most performant algorithm and are prone to overfitting due to small variations in the training data. This can result in a completely different tree. This is why people often turn to ensemble models like Bagged Trees and Random Forests. These consist of multiple decision trees trained on bootstrapped data and aggregated to achieve better predictive performance than any single tree could offer. This tutorial includes the following: 

    What is Bagging

    What Makes Random Forests Different

    Training and Tuning a Random Forest using Scikit-Learn

    Calculating and Interpreting Feature Importance

    Visualizing Individual Decision Trees in a Random Forest

    As always, the code used in this tutorial is available on my GitHub. A video version of this tutorial is also available on my YouTube channel for those who prefer to follow along visually. With that, let’s get started!

    What is BaggingBootstrap + aggregating = Bagging. Image by Michael Galarnyk.

    Random forests can be categorized as bagging algorithms. Bagging consists of two steps:

    1.) Bootstrap sampling: Create multiple training sets by randomly drawing samples with replacement from the original dataset. These new training sets, called bootstrapped datasets, typically contain the same number of rows as the original dataset, but individual rows may appear multiple times or not at all. On average, each bootstrapped dataset contains about 63.2% of the unique rows from the original data. The remaining ~36.8% of rows are left out and can be used for out-of-bagevaluation. For more on this concept, see my sampling with and without replacement blog post.

    2.) Aggregating predictions: Each bootstrapped dataset is used to train a different decision tree model. The final prediction is made by combining the outputs of all individual trees. For classification, this is typically done through majority voting. For regression, predictions are averaged.

    Training each tree on a different bootstrapped sample introduces variation across trees. While this doesn’t fully eliminate correlation—especially when certain features dominate—it helps reduce overfitting when combined with aggregation. Averaging the predictions of many such trees reduces the overall variance of the ensemble, improving generalization.

    What Makes Random Forests Different

    In contrast to some other bagged trees algorithms, for each decision tree in random forests, only a subset of features is randomly selected at each decision node and the best split feature from the subset is used. Image by Michael Galarnyk.

    Suppose there’s a single strong feature in your dataset. In bagged trees, each tree may repeatedly split on that feature, leading to correlated trees and less benefit from aggregation. Random Forests reduce this issue by introducing further randomness. Specifically, they change how splits are selected during training:

    1). Create N bootstrapped datasets. Note that while bootstrapping is commonly used in Random Forests, it is not strictly necessary because step 2introduces sufficient diversity among the trees.

    2). For each tree, at each node, a random subset of features is selected as candidates, and the best split is chosen from that subset. In scikit-learn, this is controlled by the max_features parameter, which defaults to 'sqrt' for classifiers and 1 for regressors.

    3). Aggregating predictions: vote for classification and average for regression.

    Note: Random Forests use sampling with replacement for bootstrapped datasets and sampling without replacement for selecting a subset of features. 

    Sampling with replacement procedure. Image by Michael Galarnyk

    Out-of-BagScore

    Because ~36.8% of training data is excluded from any given tree, you can use this holdout portion to evaluate that tree’s predictions. Scikit-learn allows this via the oob_score=True parameter, providing an efficient way to estimate generalization error. You’ll see this parameter used in the training example later in the tutorial.

    Training and Tuning a Random Forest in Scikit-Learn

    Random Forests remain a strong baseline for tabular data thanks to their simplicity, interpretability, and ability to parallelize since each tree is trained independently. This section demonstrates how to load data, perform a train test split, train a baseline model, tune hyperparameters using grid search, and evaluate the final model on the test set.

    Step 1: Train a Baseline Model

    Before tuning, it’s good practice to train a baseline model using reasonable defaults. This gives you an initial sense of performance and lets you validate generalization using the out-of-bagscore, which is built into bagging-based models like Random Forests. This example uses the House Sales in King County dataset, which contains property sales from the Seattle area between May 2014 and May 2015. This approach allows us to reserve the test set for final evaluation after tuning.

    Python"># Import libraries

    # Some imports are only used later in the tutorial
    import matplotlib.pyplot as plt

    import numpy as np

    import pandas as pd

    # Dataset: Breast Cancer Wisconsin# Source: UCI Machine Learning Repository
    # License: CC BY 4.0
    from sklearn.datasets import load_breast_cancer

    from sklearn.ensemble import RandomForestClassifier

    from sklearn.ensemble import RandomForestRegressor

    from sklearn.inspection import permutation_importance

    from sklearn.model_selection import GridSearchCV, train_test_split

    from sklearn import tree

    # Load dataset
    # Dataset: House Sales in King County# License CC0 1.0 Universal
    url = ';

    df = pd.read_csvcolumns =df = df# Define features and target

    X = df.dropy = df# Train/test split

    X_train, X_test, y_train, y_test = train_test_split# Train baseline Random Forest

    reg = RandomForestRegressorreg.fit# Evaluate baseline performance using OOB score

    printStep 2: Tune Hyperparameters with Grid Search

    While the baseline model gives a strong starting point, performance can often be improved by tuning key hyperparameters. Grid search cross-validation, as implemented by GridSearchCV, systematically explores combinations of hyperparameters and uses cross-validation to evaluate each one, selecting the configuration with the highest validation performance.The most commonly tuned hyperparameters include:

    n_estimators: The number of decision trees in the forest. More trees can improve accuracy but increase training time.

    max_features: The number of features to consider when looking for the best split. Lower values reduce correlation between trees.

    max_depth: The maximum depth of each tree. Shallower trees are faster but may underfit.

    min_samples_split: The minimum number of samples required to split an internal node. Higher values can reduce overfitting.

    min_samples_leaf: The minimum number of samples required to be at a leaf node. Helps control tree size.

    bootstrap: Whether bootstrap samples are used when building trees. If False, the whole dataset is used.

    param_grid = {

        'n_estimators':,

        'max_features':,

        'max_depth':,

        'min_samples_split':,

        'min_samples_leaf':}

    # Initialize model

    rf = RandomForestRegressorgrid_search = GridSearchCVgrid_search.fitprintprintStep 3: Evaluate Final Model on Test Set

    Now that we’ve selected the best-performing model based on cross-validation, we can evaluate it on the held-out test set to estimate its generalization performance.

    # Evaluate final model on test set

    best_model = grid_search.best_estimator_

    print: {best_model.score:.3f}")

    Calculating Random Forest Feature Importance

    One of the key advantages of Random Forests is their interpretability — something that large language modelsoften lack. While LLMs are powerful, they typically function as black boxes and can exhibit biases that are difficult to identify. In contrast, scikit-learn supports two main methods for measuring feature importance in Random Forests: Mean Decrease in Impurity and Permutation Importance.

    1). Mean Decrease in Impurity: Also known as Gini importance, this method calculates the total reduction in impurity brought by each feature across all trees. This is fast and built into the model via reg.feature_importances_. However, impurity-based feature importances can be misleading, especially for features with high cardinality, as these features are more likely to be chosen simply because they provide more potential split points.

    importances = reg.feature_importances_

    feature_names = X.columns

    sorted_idx = np.argsortfor i in sorted_idx:

        print2). Permutation Importance: This method assesses the decrease in model performance when a single feature’s values are randomly shuffled. Unlike MDI, it accounts for feature interactions and correlation. It is more reliable but also more computationally expensive.

    # Perform permutation importance on the test set

    perm_importance = permutation_importancesorted_idx = perm_importance.importances_mean.argsortfor i in sorted_idx:

        printIt is important to note that our geographic features lat and long are also useful for visualization as the plot below shows. It’s likely that companies like Zillow leverage location information extensively in their valuation models.

    Housing Price percentile for King County. Image by Michael Galarnyk.

    Visualizing Individual Decision Trees in a Random Forest

    A Random Forest consists of multiple decision trees—one for each estimator specified via the n_estimators parameter. After training the model, you can access these individual trees through the .estimators_ attribute. Visualizing a few of these trees can help illustrate how differently each one splits the data due to bootstrapped training samples and random feature selection at each split. While the earlier example used a RandomForestRegressor, here we demonstrate this visualization using a RandomForestClassifier trained on the Breast Cancer Wisconsin datasetto highlight Random Forests’ versatility for both regression and classification tasks. This short video demonstrates what 100 trained estimators from this dataset look like.

    Fit a Random Forest Model using Scikit-Learn

    # Load the Breast CancerDataset

    data = load_breast_cancerdf = pd.DataFramedf= data.target

    # Arrange Data into Features Matrix and Target Vector

    X = df.locy = df.loc.values

    # Split the data into training and testing sets

    X_train, X_test, Y_train, Y_test = train_test_split# Random Forests in `scikit-learn`rf = RandomForestClassifierrf.fitPlotting Individual Estimatorsfrom a Random Forest using Matplotlib

    You can now view all the individual trees from the fitted model. 

    rf.estimators_

    You can now visualize individual trees. The code below visualizes the first decision tree.

    fn=data.feature_names

    cn=data.target_names

    fig, axes = plt.subplots, dpi=800)

    tree.plot_tree;

    fig.savefigAlthough plotting many trees can be difficult to interpret, you may wish to explore the variety across estimators. The following example shows how to visualize the first five decision trees in the forest:

    # This may not the best way to view each estimator as it is small

    fig, axes = plt.subplots, dpi=3000)

    for index in range:

        tree.plot_tree    axes.set_titlefig.savefigConclusion

    Random forests consist of multiple decision trees trained on bootstrapped data in order to achieve better predictive performance than could be obtained from any of the individual decision trees. If you have questions or thoughts on the tutorial, feel free to reach out through YouTube or X.
    The post Understanding Random Forest using Pythonappeared first on Towards Data Science.
    #understanding #random #forest #using #python
    Understanding Random Forest using Python (scikit-learn)
    Decision trees are a popular supervised learning algorithm with benefits that include being able to be used for both regression and classification as well as being easy to interpret. However, decision trees aren’t the most performant algorithm and are prone to overfitting due to small variations in the training data. This can result in a completely different tree. This is why people often turn to ensemble models like Bagged Trees and Random Forests. These consist of multiple decision trees trained on bootstrapped data and aggregated to achieve better predictive performance than any single tree could offer. This tutorial includes the following:  What is Bagging What Makes Random Forests Different Training and Tuning a Random Forest using Scikit-Learn Calculating and Interpreting Feature Importance Visualizing Individual Decision Trees in a Random Forest As always, the code used in this tutorial is available on my GitHub. A video version of this tutorial is also available on my YouTube channel for those who prefer to follow along visually. With that, let’s get started! What is BaggingBootstrap + aggregating = Bagging. Image by Michael Galarnyk. Random forests can be categorized as bagging algorithms. Bagging consists of two steps: 1.) Bootstrap sampling: Create multiple training sets by randomly drawing samples with replacement from the original dataset. These new training sets, called bootstrapped datasets, typically contain the same number of rows as the original dataset, but individual rows may appear multiple times or not at all. On average, each bootstrapped dataset contains about 63.2% of the unique rows from the original data. The remaining ~36.8% of rows are left out and can be used for out-of-bagevaluation. For more on this concept, see my sampling with and without replacement blog post. 2.) Aggregating predictions: Each bootstrapped dataset is used to train a different decision tree model. The final prediction is made by combining the outputs of all individual trees. For classification, this is typically done through majority voting. For regression, predictions are averaged. Training each tree on a different bootstrapped sample introduces variation across trees. While this doesn’t fully eliminate correlation—especially when certain features dominate—it helps reduce overfitting when combined with aggregation. Averaging the predictions of many such trees reduces the overall variance of the ensemble, improving generalization. What Makes Random Forests Different In contrast to some other bagged trees algorithms, for each decision tree in random forests, only a subset of features is randomly selected at each decision node and the best split feature from the subset is used. Image by Michael Galarnyk. Suppose there’s a single strong feature in your dataset. In bagged trees, each tree may repeatedly split on that feature, leading to correlated trees and less benefit from aggregation. Random Forests reduce this issue by introducing further randomness. Specifically, they change how splits are selected during training: 1). Create N bootstrapped datasets. Note that while bootstrapping is commonly used in Random Forests, it is not strictly necessary because step 2introduces sufficient diversity among the trees. 2). For each tree, at each node, a random subset of features is selected as candidates, and the best split is chosen from that subset. In scikit-learn, this is controlled by the max_features parameter, which defaults to 'sqrt' for classifiers and 1 for regressors. 3). Aggregating predictions: vote for classification and average for regression. Note: Random Forests use sampling with replacement for bootstrapped datasets and sampling without replacement for selecting a subset of features.  Sampling with replacement procedure. Image by Michael Galarnyk Out-of-BagScore Because ~36.8% of training data is excluded from any given tree, you can use this holdout portion to evaluate that tree’s predictions. Scikit-learn allows this via the oob_score=True parameter, providing an efficient way to estimate generalization error. You’ll see this parameter used in the training example later in the tutorial. Training and Tuning a Random Forest in Scikit-Learn Random Forests remain a strong baseline for tabular data thanks to their simplicity, interpretability, and ability to parallelize since each tree is trained independently. This section demonstrates how to load data, perform a train test split, train a baseline model, tune hyperparameters using grid search, and evaluate the final model on the test set. Step 1: Train a Baseline Model Before tuning, it’s good practice to train a baseline model using reasonable defaults. This gives you an initial sense of performance and lets you validate generalization using the out-of-bagscore, which is built into bagging-based models like Random Forests. This example uses the House Sales in King County dataset, which contains property sales from the Seattle area between May 2014 and May 2015. This approach allows us to reserve the test set for final evaluation after tuning. Python"># Import libraries # Some imports are only used later in the tutorial import matplotlib.pyplot as plt import numpy as np import pandas as pd # Dataset: Breast Cancer Wisconsin# Source: UCI Machine Learning Repository # License: CC BY 4.0 from sklearn.datasets import load_breast_cancer from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import RandomForestRegressor from sklearn.inspection import permutation_importance from sklearn.model_selection import GridSearchCV, train_test_split from sklearn import tree # Load dataset # Dataset: House Sales in King County# License CC0 1.0 Universal url = '; df = pd.read_csvcolumns =df = df# Define features and target X = df.dropy = df# Train/test split X_train, X_test, y_train, y_test = train_test_split# Train baseline Random Forest reg = RandomForestRegressorreg.fit# Evaluate baseline performance using OOB score printStep 2: Tune Hyperparameters with Grid Search While the baseline model gives a strong starting point, performance can often be improved by tuning key hyperparameters. Grid search cross-validation, as implemented by GridSearchCV, systematically explores combinations of hyperparameters and uses cross-validation to evaluate each one, selecting the configuration with the highest validation performance.The most commonly tuned hyperparameters include: n_estimators: The number of decision trees in the forest. More trees can improve accuracy but increase training time. max_features: The number of features to consider when looking for the best split. Lower values reduce correlation between trees. max_depth: The maximum depth of each tree. Shallower trees are faster but may underfit. min_samples_split: The minimum number of samples required to split an internal node. Higher values can reduce overfitting. min_samples_leaf: The minimum number of samples required to be at a leaf node. Helps control tree size. bootstrap: Whether bootstrap samples are used when building trees. If False, the whole dataset is used. param_grid = {     'n_estimators':,     'max_features':,     'max_depth':,     'min_samples_split':,     'min_samples_leaf':} # Initialize model rf = RandomForestRegressorgrid_search = GridSearchCVgrid_search.fitprintprintStep 3: Evaluate Final Model on Test Set Now that we’ve selected the best-performing model based on cross-validation, we can evaluate it on the held-out test set to estimate its generalization performance. # Evaluate final model on test set best_model = grid_search.best_estimator_ print: {best_model.score:.3f}") Calculating Random Forest Feature Importance One of the key advantages of Random Forests is their interpretability — something that large language modelsoften lack. While LLMs are powerful, they typically function as black boxes and can exhibit biases that are difficult to identify. In contrast, scikit-learn supports two main methods for measuring feature importance in Random Forests: Mean Decrease in Impurity and Permutation Importance. 1). Mean Decrease in Impurity: Also known as Gini importance, this method calculates the total reduction in impurity brought by each feature across all trees. This is fast and built into the model via reg.feature_importances_. However, impurity-based feature importances can be misleading, especially for features with high cardinality, as these features are more likely to be chosen simply because they provide more potential split points. importances = reg.feature_importances_ feature_names = X.columns sorted_idx = np.argsortfor i in sorted_idx:     print2). Permutation Importance: This method assesses the decrease in model performance when a single feature’s values are randomly shuffled. Unlike MDI, it accounts for feature interactions and correlation. It is more reliable but also more computationally expensive. # Perform permutation importance on the test set perm_importance = permutation_importancesorted_idx = perm_importance.importances_mean.argsortfor i in sorted_idx:     printIt is important to note that our geographic features lat and long are also useful for visualization as the plot below shows. It’s likely that companies like Zillow leverage location information extensively in their valuation models. Housing Price percentile for King County. Image by Michael Galarnyk. Visualizing Individual Decision Trees in a Random Forest A Random Forest consists of multiple decision trees—one for each estimator specified via the n_estimators parameter. After training the model, you can access these individual trees through the .estimators_ attribute. Visualizing a few of these trees can help illustrate how differently each one splits the data due to bootstrapped training samples and random feature selection at each split. While the earlier example used a RandomForestRegressor, here we demonstrate this visualization using a RandomForestClassifier trained on the Breast Cancer Wisconsin datasetto highlight Random Forests’ versatility for both regression and classification tasks. This short video demonstrates what 100 trained estimators from this dataset look like. Fit a Random Forest Model using Scikit-Learn # Load the Breast CancerDataset data = load_breast_cancerdf = pd.DataFramedf= data.target # Arrange Data into Features Matrix and Target Vector X = df.locy = df.loc.values # Split the data into training and testing sets X_train, X_test, Y_train, Y_test = train_test_split# Random Forests in `scikit-learn`rf = RandomForestClassifierrf.fitPlotting Individual Estimatorsfrom a Random Forest using Matplotlib You can now view all the individual trees from the fitted model.  rf.estimators_ You can now visualize individual trees. The code below visualizes the first decision tree. fn=data.feature_names cn=data.target_names fig, axes = plt.subplots, dpi=800) tree.plot_tree; fig.savefigAlthough plotting many trees can be difficult to interpret, you may wish to explore the variety across estimators. The following example shows how to visualize the first five decision trees in the forest: # This may not the best way to view each estimator as it is small fig, axes = plt.subplots, dpi=3000) for index in range:     tree.plot_tree    axes.set_titlefig.savefigConclusion Random forests consist of multiple decision trees trained on bootstrapped data in order to achieve better predictive performance than could be obtained from any of the individual decision trees. If you have questions or thoughts on the tutorial, feel free to reach out through YouTube or X. The post Understanding Random Forest using Pythonappeared first on Towards Data Science. #understanding #random #forest #using #python
    TOWARDSDATASCIENCE.COM
    Understanding Random Forest using Python (scikit-learn)
    Decision trees are a popular supervised learning algorithm with benefits that include being able to be used for both regression and classification as well as being easy to interpret. However, decision trees aren’t the most performant algorithm and are prone to overfitting due to small variations in the training data. This can result in a completely different tree. This is why people often turn to ensemble models like Bagged Trees and Random Forests. These consist of multiple decision trees trained on bootstrapped data and aggregated to achieve better predictive performance than any single tree could offer. This tutorial includes the following:  What is Bagging What Makes Random Forests Different Training and Tuning a Random Forest using Scikit-Learn Calculating and Interpreting Feature Importance Visualizing Individual Decision Trees in a Random Forest As always, the code used in this tutorial is available on my GitHub. A video version of this tutorial is also available on my YouTube channel for those who prefer to follow along visually. With that, let’s get started! What is Bagging (Bootstrap Aggregating) Bootstrap + aggregating = Bagging. Image by Michael Galarnyk. Random forests can be categorized as bagging algorithms (bootstrap aggregating). Bagging consists of two steps: 1.) Bootstrap sampling: Create multiple training sets by randomly drawing samples with replacement from the original dataset. These new training sets, called bootstrapped datasets, typically contain the same number of rows as the original dataset, but individual rows may appear multiple times or not at all. On average, each bootstrapped dataset contains about 63.2% of the unique rows from the original data. The remaining ~36.8% of rows are left out and can be used for out-of-bag (OOB) evaluation. For more on this concept, see my sampling with and without replacement blog post. 2.) Aggregating predictions: Each bootstrapped dataset is used to train a different decision tree model. The final prediction is made by combining the outputs of all individual trees. For classification, this is typically done through majority voting. For regression, predictions are averaged. Training each tree on a different bootstrapped sample introduces variation across trees. While this doesn’t fully eliminate correlation—especially when certain features dominate—it helps reduce overfitting when combined with aggregation. Averaging the predictions of many such trees reduces the overall variance of the ensemble, improving generalization. What Makes Random Forests Different In contrast to some other bagged trees algorithms, for each decision tree in random forests, only a subset of features is randomly selected at each decision node and the best split feature from the subset is used. Image by Michael Galarnyk. Suppose there’s a single strong feature in your dataset. In bagged trees, each tree may repeatedly split on that feature, leading to correlated trees and less benefit from aggregation. Random Forests reduce this issue by introducing further randomness. Specifically, they change how splits are selected during training: 1). Create N bootstrapped datasets. Note that while bootstrapping is commonly used in Random Forests, it is not strictly necessary because step 2 (random feature selection) introduces sufficient diversity among the trees. 2). For each tree, at each node, a random subset of features is selected as candidates, and the best split is chosen from that subset. In scikit-learn, this is controlled by the max_features parameter, which defaults to 'sqrt' for classifiers and 1 for regressors (equivalent to bagged trees). 3). Aggregating predictions: vote for classification and average for regression. Note: Random Forests use sampling with replacement for bootstrapped datasets and sampling without replacement for selecting a subset of features.  Sampling with replacement procedure. Image by Michael Galarnyk Out-of-Bag (OOB) Score Because ~36.8% of training data is excluded from any given tree, you can use this holdout portion to evaluate that tree’s predictions. Scikit-learn allows this via the oob_score=True parameter, providing an efficient way to estimate generalization error. You’ll see this parameter used in the training example later in the tutorial. Training and Tuning a Random Forest in Scikit-Learn Random Forests remain a strong baseline for tabular data thanks to their simplicity, interpretability, and ability to parallelize since each tree is trained independently. This section demonstrates how to load data, perform a train test split, train a baseline model, tune hyperparameters using grid search, and evaluate the final model on the test set. Step 1: Train a Baseline Model Before tuning, it’s good practice to train a baseline model using reasonable defaults. This gives you an initial sense of performance and lets you validate generalization using the out-of-bag (OOB) score, which is built into bagging-based models like Random Forests. This example uses the House Sales in King County dataset (CCO 1.0 Universal License), which contains property sales from the Seattle area between May 2014 and May 2015. This approach allows us to reserve the test set for final evaluation after tuning. Python"># Import libraries # Some imports are only used later in the tutorial import matplotlib.pyplot as plt import numpy as np import pandas as pd # Dataset: Breast Cancer Wisconsin (Diagnostic) # Source: UCI Machine Learning Repository # License: CC BY 4.0 from sklearn.datasets import load_breast_cancer from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import RandomForestRegressor from sklearn.inspection import permutation_importance from sklearn.model_selection import GridSearchCV, train_test_split from sklearn import tree # Load dataset # Dataset: House Sales in King County (May 2014–May 2015) # License CC0 1.0 Universal url = 'https://raw.githubusercontent.com/mGalarnyk/Tutorial_Data/master/King_County/kingCountyHouseData.csv' df = pd.read_csv(url) columns = ['bedrooms',             'bathrooms',             'sqft_living',             'sqft_lot',              'floors',              'waterfront',              'view',              'condition',              'grade',              'sqft_above',              'sqft_basement',              'yr_built',              'yr_renovated',              'lat',              'long',              'sqft_living15',              'sqft_lot15',              'price'] df = df[columns] # Define features and target X = df.drop(columns='price') y = df['price'] # Train/test split X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) # Train baseline Random Forest reg = RandomForestRegressor(     n_estimators=100,        # number of trees     max_features=1/3,        # fraction of features considered at each split     oob_score=True,          # enables out-of-bag evaluation     random_state=0 ) reg.fit(X_train, y_train) # Evaluate baseline performance using OOB score print(f"Baseline OOB score: {reg.oob_score_:.3f}") Step 2: Tune Hyperparameters with Grid Search While the baseline model gives a strong starting point, performance can often be improved by tuning key hyperparameters. Grid search cross-validation, as implemented by GridSearchCV, systematically explores combinations of hyperparameters and uses cross-validation to evaluate each one, selecting the configuration with the highest validation performance.The most commonly tuned hyperparameters include: n_estimators: The number of decision trees in the forest. More trees can improve accuracy but increase training time. max_features: The number of features to consider when looking for the best split. Lower values reduce correlation between trees. max_depth: The maximum depth of each tree. Shallower trees are faster but may underfit. min_samples_split: The minimum number of samples required to split an internal node. Higher values can reduce overfitting. min_samples_leaf: The minimum number of samples required to be at a leaf node. Helps control tree size. bootstrap: Whether bootstrap samples are used when building trees. If False, the whole dataset is used. param_grid = {     'n_estimators': [100],     'max_features': ['sqrt', 'log2', None],     'max_depth': [None, 5, 10, 20],     'min_samples_split': [2, 5],     'min_samples_leaf': [1, 2] } # Initialize model rf = RandomForestRegressor(random_state=0, oob_score=True) grid_search = GridSearchCV(     estimator=rf,     param_grid=param_grid,     cv=5,             # 5-fold cross-validation     scoring='r2',     # evaluation metric     n_jobs=-1         # use all available CPU cores ) grid_search.fit(X_train, y_train) print(f"Best parameters: {grid_search.best_params_}") print(f"Best R^2 score: {grid_search.best_score_:.3f}") Step 3: Evaluate Final Model on Test Set Now that we’ve selected the best-performing model based on cross-validation, we can evaluate it on the held-out test set to estimate its generalization performance. # Evaluate final model on test set best_model = grid_search.best_estimator_ print(f"Test R^2 score (final model): {best_model.score(X_test, y_test):.3f}") Calculating Random Forest Feature Importance One of the key advantages of Random Forests is their interpretability — something that large language models (LLMs) often lack. While LLMs are powerful, they typically function as black boxes and can exhibit biases that are difficult to identify. In contrast, scikit-learn supports two main methods for measuring feature importance in Random Forests: Mean Decrease in Impurity and Permutation Importance. 1). Mean Decrease in Impurity (MDI): Also known as Gini importance, this method calculates the total reduction in impurity brought by each feature across all trees. This is fast and built into the model via reg.feature_importances_. However, impurity-based feature importances can be misleading, especially for features with high cardinality (many unique values), as these features are more likely to be chosen simply because they provide more potential split points. importances = reg.feature_importances_ feature_names = X.columns sorted_idx = np.argsort(importances)[::-1] for i in sorted_idx:     print(f"{feature_names[i]}: {importances[i]:.3f}") 2). Permutation Importance: This method assesses the decrease in model performance when a single feature’s values are randomly shuffled. Unlike MDI, it accounts for feature interactions and correlation. It is more reliable but also more computationally expensive. # Perform permutation importance on the test set perm_importance = permutation_importance(reg, X_test, y_test, n_repeats=10, random_state=0) sorted_idx = perm_importance.importances_mean.argsort()[::-1] for i in sorted_idx:     print(f"{X.columns[i]}: {perm_importance.importances_mean[i]:.3f}") It is important to note that our geographic features lat and long are also useful for visualization as the plot below shows. It’s likely that companies like Zillow leverage location information extensively in their valuation models. Housing Price percentile for King County. Image by Michael Galarnyk. Visualizing Individual Decision Trees in a Random Forest A Random Forest consists of multiple decision trees—one for each estimator specified via the n_estimators parameter. After training the model, you can access these individual trees through the .estimators_ attribute. Visualizing a few of these trees can help illustrate how differently each one splits the data due to bootstrapped training samples and random feature selection at each split. While the earlier example used a RandomForestRegressor, here we demonstrate this visualization using a RandomForestClassifier trained on the Breast Cancer Wisconsin dataset (CC BY 4.0 license) to highlight Random Forests’ versatility for both regression and classification tasks. This short video demonstrates what 100 trained estimators from this dataset look like. Fit a Random Forest Model using Scikit-Learn # Load the Breast Cancer (Diagnostic) Dataset data = load_breast_cancer() df = pd.DataFrame(data.data, columns=data.feature_names) df['target'] = data.target # Arrange Data into Features Matrix and Target Vector X = df.loc[:, df.columns != 'target'] y = df.loc[:, 'target'].values # Split the data into training and testing sets X_train, X_test, Y_train, Y_test = train_test_split(X, y, random_state=0) # Random Forests in `scikit-learn` (with N = 100) rf = RandomForestClassifier(n_estimators=100,                             random_state=0) rf.fit(X_train, Y_train) Plotting Individual Estimators (decision trees) from a Random Forest using Matplotlib You can now view all the individual trees from the fitted model.  rf.estimators_ You can now visualize individual trees. The code below visualizes the first decision tree. fn=data.feature_names cn=data.target_names fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (4,4), dpi=800) tree.plot_tree(rf.estimators_[0],                feature_names = fn,                 class_names=cn,                filled = True); fig.savefig('rf_individualtree.png') Although plotting many trees can be difficult to interpret, you may wish to explore the variety across estimators. The following example shows how to visualize the first five decision trees in the forest: # This may not the best way to view each estimator as it is small fig, axes = plt.subplots(nrows=1, ncols=5, figsize=(10, 2), dpi=3000) for index in range(5):     tree.plot_tree(rf.estimators_[index],                    feature_names=fn,                    class_names=cn,                    filled=True,                    ax=axes[index])     axes[index].set_title(f'Estimator: {index}', fontsize=11) fig.savefig('rf_5trees.png') Conclusion Random forests consist of multiple decision trees trained on bootstrapped data in order to achieve better predictive performance than could be obtained from any of the individual decision trees. If you have questions or thoughts on the tutorial, feel free to reach out through YouTube or X. The post Understanding Random Forest using Python (scikit-learn) appeared first on Towards Data Science.
    0 Commentarios 0 Acciones
  • How To Build Stylized Water Shader: Design & Implementation For Nimue

    NimueIntroductionFor three semesters, our student team has been hard at work on the prototype for Nimue, a 3D platformer in which you play an enchanted princess who lost her memories. She needs to find her way through the castle ruins on a misty lake to uncover her past. Water is a visual core element of this game prototype, so we took extra care in its development. In this article, we will take an in-depth look at the design and technical implementation of a lake water material.The first prototype of Nimue can be played on itch.io soon. A link to our shader for use in your own projects can be found at the end of this article.Taxonomy of WaterBefore we dive into the design decisions and technical implementation, we present a simplified taxonomy of visual water components to better understand the requirements of its representation:RiMEWind WavesWaves generated by wind, which form on an open water surface, can be divided into capillary waves and gravity waves. Capillary waves, or ripples, are small, short-wavelength waves caused by weak winds affecting surface tension in calm water. They can overlap longer and larger gravity waves. How these physically complex wave types are represented in stylized video games varies depending on the respective style. Both types are usually heavily simplified in form and motion, and capillary waves are sometimes omitted entirely to reduce detail.Sea of ThievesFoam PatternsFoam patterns refer to white foam crests that form on a water surface without breaking against an obstacle or shoreline. In reality, this effect occurs when different water layers collide, and waves become steeper until their peaks collapse, and the resulting bubbles and drops scatter the sunlight. Stylized foam patterns can be found in many video game water representations and can easily be abstracted into patterns. Such patterns contribute to a cartoon look and can sometimes even replace waveforms entirely.The Legend of Zelda: The Wind WakerFoam LinesFoam lines are a very common water element in video games, represented as white graphical lines surrounding shorelines and obstacles like rocks. They typically reference two different water phenomena: foam forming around obstacles due to wave breaking, and foam along shorelines, resulting from wave breaking and the mixing of algaes with organic and artificial substances.Foam lines can have different visual appearances depending on the surface angle: The shallower the angle, the wider the foam effect. Due to the weaker waves, distinctive foam lines are rarely observed on natural lakes, but they can be included in a stylization for aesthetic purposes. Animal Crossing: New HorizonsReflectionsWhen light hits a water surface, it can either be reflectedor transmitted into the water, where it may be absorbed, scattered, or reflected back through the surface. The Fresnel effect describes the perceived balance between reflection and transmission: at steep angles, more transmitted light reaches the eye, making the water appear more translucent, while at shallow angles, increased reflection makes it appear more opaqueIn stylized video games, implementations of water reflections vary: RiME, for example, imitates the Fresnel effect but does not reflect the environment at all, only a simple, otherwise invisible cube map. Wind Waker, on the other hand, completely foregoes reflection calculations and renders a flat-shaded water surface.RiMETranslucencyAs an inhomogeneous medium, water scatters some of the transmitted light before it can be reflected back to the surface. This is why water is described as translucent rather than transparent. Some scattered light is not reflected back but absorbed, reducing intensity and shifting color toward the least absorbed wavelengths, typically blue, blue-green, or turquoise. Increased distance amplifies scattering and absorption, altering color perception. Modern real-time engines simulate these effects, including absorption-based color variation with depth. However, stylized games often simplify or omit transmission entirely, rendering water as an opaque surface.RiMERefractionAn additional aspect of water transmission is refraction, the bending of light as it transitions between air and water due to their differing densities. This causes light to bend toward the normal upon entering the water, creating the apparent distortion of submerged objects. Refraction effects also commonly appear in stylized water rendering. Kirby's Forgotten Land, for example, showcases two key visual characteristics of refraction: distortion increases with steeper viewing angles and is amplified by ripples on the water's surface.Kirby and the Forgotten LandCausticsCaustic patterns form when light rays are focused by a curved water surface, projecting bundled light patterns onto underwater surfaces or even back to surfaces above water. These patterns are influenced by the clarity of the water, the depth of the water, and the strength of the light source. They contribute greatly to the atmosphere of virtual worlds and are often found in stylized games, although only as simplistic representations.The Legend of Zelda: Ocarina of Time 3DDesign DecisionsDue to the fact that the setting of Nimue is a lake with a calm overall atmosphere, the decision was made to use very reduced gravity waves, as a calm water surface underlines this atmosphere. Capillary waves have too high a level of detail for the stylistic requirements of Nimue and were, therefore, not implemented.NimueShapesThe mood in Nimue can be summarized as calm and mystical. The design language of Nimue is graphic, rounded, and elegant. Shapes are vertically elongated and highly abstracted. Convex corners are always rounded or have a strong bevel, while concave corners are pointed to prevent the overall mass of objects from becoming too rounded.ColorsNimue uses mostly broken colors and pastels to create a serene, reflective mood and highlight the player's character with her saturated blue tones. Platforms and obstacles are depicted with a lower tonal valueto increase their visibility. Overall, the game world is kept in very unsaturated shades of blue, with the atmospheric depth, i.e., the sky and objects in the distance, falling into the complementary orange range. Shades of green and yellow are either completely avoided or extremely desaturated. The resulting reduced color palette additionally supports the atmosphere and makes it appear more harmonious.Color gamut & value/tone tests Hue, Tone & SaturationSince the color of the water, with its hue, tone, and saturation, is technically achieved by several components, a 2D mockup was first designed to more easily compare different colors in the environment. Here it could be observed that both the low and the high tonal value formed too great a contrast to the rest of the environment and thus placed an undesirable focus on the water. Therefore, the medium tone value was chosen.The hue and saturation were tested in relativity to the sky, the player character, and the background. Here, too, the color variant that harmonizes the most with the rest of the environment and contrasts the least was chosen.Foam LinesFor the design of the foam lines, we proceeded in the same way as for the color selection: In this case, a screenshot of the test scene was used as the basis for three overpaints to try out different foam lines on the stones in the scene. Version 3 offers the greatest scope in terms of movement within the patterns. Due to this, and because of the greater visual interest, we opted for variant 3. Following the mockup, the texture was prepared so that it could be technically implemented.ReflectionThe reflection of the water surface contributes to how realistic the water looks, as one would always expect a reflection with natural water, depending on the angle. However, a reflection could also contribute to the overall appearance of the water becoming less calm. The romantic character created by the reflection of diffuse light on water is more present in version 1.In addition, the soft, wafting shapes created by the reflection fit in well with the art style. A reflection is desirable, but the reflections must not take up too much focus. Ideally, the water should be lighter in tone, and the reflections should be present but less pronounced. Reflection intensityRefraction & CausticsEven though most light in our water gets absorbed, we noticed an improvement in the believability of the ground right underneath the water's surface when utilizing refraction together with the waveforms. When it comes to caustics, the diffuse lighting conditions of our scene would make visible caustic patterns physically implausible, but it felt right aesthetically, which is why we included it anyway.Technical Realization in Unreal Engine 5When building a water material in Unreal, choosing the right shading model and blend mode is crucial. While a Default Lit Translucent material with Surface Forward Shading offers the most control, it is very costly to render. The more efficient choice is the Single Layer Water shading model introduced in Unreal 4.27, which supports light absorption, scattering, reflection, refraction, and shadowing at a lower instruction count. However, there are some downsides. For example, as it only uses a single depth layer, it lacks back-face rendering, making it less suitable for underwater views. And while still quite expensive by itself, its benefits outweigh the drawbacks of our stylized water material.WaveformsStarting with the waveforms, we used panning normal maps to simulate the rather calm low-altitude gravity waves. The approach here is simple: create a wave normal map in Substance 3D Designer, sample it twice, and continuously offset the samples' UV coordinates in opposing directions at different speeds. Give one of the two samples a higher speed and normal intensity to create a sense of wind direction. This panning operation does not need to run in the fragment shader, you can move it to the vertex shader through the Vertex Interpolator without quality loss and thereby reduce the instruction count.Texture RepetitionTo reduce visible tiling, we used three simple and fairly efficient tricks. First, we offset the UVs of the Wave Samplers with a large panning noise texture to dynamically distort the wave patterns. Second, we used another sampler of that noise texture with different tiling, speed, and direction to modulate the strength of the normal maps across the surface. We sampled this noise texture four times with different variables in the material, which is a lot, but we reused them many times for most of the visual features of our water. Third, we sampled the pixel depth of the surface to mask out the waves that were far from the camera so that there were no waves in the far distance.Vertex DisplacementWhile these normal waves are enough to create the illusion of altitude on the water surface itself, they are lacking when it comes to the intersections around objects in the water, as these intersections are static without any actual vertex displacement. To fix that, two very simple sine operationswere added to drive the World Position Offset of the water mesh on the Z-axis. To keep the polycounts in check, we built a simple blueprint grid system that spawns high-res plane meshes at the center in a variable radius, and low-res plane meshes around that. This enables the culling of non-visible planes and the use of a less complex version of the water material for distant planes, where features like WPO are not needed.ColorThe general transmission amount is controlled by the opacity input of the material output, but scattering and absorption are defined via the Single Layer Water material output. The inputs Scattering Coefficients and Absorption Coefficients, which are responsible for reproducing how and how far different wavelengths travel through water, are decisive here. We use two scattering colors as parameters, which are interpolated depending on the camera distance. Close to the camera, the blue scattering colordominates, while at a distance, the orange scattering colortakes over. The advantage is a separation of the water's color from the sky's color and, thus, higher artistic control.Reflections & RefractionReflections in the Single Layer Water shading model are as usual determined by the inputs for Specularand Roughness. In our case, however, we use Lumen reflections for their accuracy and quality, and as of Unreal 5.4, the Single Layer Water model’s roughness calculation does not work with Lumen reflections. It forces mirror reflections, no matter the value input, leaving the specular lobe unaffected. Instead, it only offsets the reflection brightness, as the specular input does.For our artistic purposes, this is fine, and we do use the roughness input to fine-tune the specular level while having the specular input as the base level. A very low value was set for the specular value to keep the reflection brightness low. We further stylized the reflections by decreasing this brightness near the camera by using the already mentioned masking method via camera to interpolate between two values. For refraction, the Pixel Normal Offset mode was used, and a scalar parameter interpolates between the base refraction and the output of the normal waves.CausticsFor the caustic effect, we created a Voronoi noise pattern by using Unreal's Noise node and exporting it with a render target. In Photoshop, the pattern was duplicated twice, rotated each, colored, and blended. This texture is then projected on the objects below by using the ColorScaleBehindWater input of the Single Layer Water Material output. The pattern is dynamically distorted by adding one of the aforementioned panning noise textures to the UV coordinates.FoamlinesWe started by creating custom meshes for foam lines and applied the earlier texture pattern, but quickly realized that such a workflow would be too cumbersome and inflexible for even a small scene, so we decided to do it procedurally. Two common methods for generating intersection masks on a plane are Depth Sampling and Distance Fields. The first works by subtracting the camera's distance to the water surface at the current pixelfrom the camera's distance to the closest scene object at that pixel. The second method is to use the node "DistanceToNearestSurface" which calculates the shortest distance between a point on the water surface and the nearest object by referencing the scene's global distance field. We used both methods to control the mask width, as each alone varies with the object's surface slope, causing undesirable variations. Combining them allowed us to switch between two different mask widths, turning off "Affect Distance Field Lighting" for shallow slopes where narrower lines are wanted.The added mask of all intersections is then used for two effects to create the foam lines: "edge foam"and "edge waves". Both are shaped with the noise samplers shown above to approximate the hand-drawn foam line texture.Foam PatternsThe same noise samplers are also used to create a sparkling foam effect, loosely imitating whitecaps/foam crests to add more visual interest to the water surface. Since it only reuses operations, this effect is very cheap. Similarly, the wave normals are used to create something like fake subsurface scattering to further distinguish the moving water surface. Interactive RipplesA third type of foam is added as interactive waves that ripple around the player character when walking through shallow water. This is done through a Render Target and particles, as demonstrated in this Unity tutorial by Minions Art. The steps described there are all easily applicable in Unreal with a Niagara System, a little Blueprint work, and common material nodes. We added a Height to Normal conversion for better visual integration into our existing wave setup. Finally, here are all those operations combined for the material inputs:NimueBest PracticesUse Single Layer Water for efficient translucency, but note it lacks back-face rendering and forces mirror reflections with Lumen;For simple low-altitude waves, pan two offset samples of a normal map at different speeds; move panning to Vertex Shader for better performance;Break up texture tiling efficiently by offsetting UVs with a large panning noise, modulating normal strength, and fading distant waves using pixel depth;Sampling one small noise texture at different scales can power this and many other features of a water shader efficiently;If high-altitude waves aren't needed, a simple sine-based WPO can suffice for vertex displacement; implement a grid system for LODs and culling of subdivided water meshes;Blend two scattering colors by camera distance for artistic watercolor control and separation from sky reflections;Combining depth sampling and distance fields to derive the foam lines allows for more flexible intersection widths but comes at a higher cost. Further ResourcesHere are some resources that helped us in the shader creation process:General shader theory and creation: tharlevfx, Ben Cloward;Interactive water in Unity: Minions Art;Another free stylized water material in Unreal by Fabian Lopez Arosa;Technical art wizardry: Ghislain Girardot.ConclusionWe hope this breakdown of our water material creation process will help you in your projects.If you want to take a look at our shader yourself or even use it for your own game projects, you can download the complete setup on Gumroad. We look forward to seeing your water shaders and exchanging ideas. Feel free to reach out if you have any questions or want to connect.Kolja Bopp, Academic SupervisorLeanna Geideck, Concept ArtistStephan zu Münster, Technical Artist
    #how #build #stylized #water #shader
    How To Build Stylized Water Shader: Design & Implementation For Nimue
    NimueIntroductionFor three semesters, our student team has been hard at work on the prototype for Nimue, a 3D platformer in which you play an enchanted princess who lost her memories. She needs to find her way through the castle ruins on a misty lake to uncover her past. Water is a visual core element of this game prototype, so we took extra care in its development. In this article, we will take an in-depth look at the design and technical implementation of a lake water material.The first prototype of Nimue can be played on itch.io soon. A link to our shader for use in your own projects can be found at the end of this article.Taxonomy of WaterBefore we dive into the design decisions and technical implementation, we present a simplified taxonomy of visual water components to better understand the requirements of its representation:RiMEWind WavesWaves generated by wind, which form on an open water surface, can be divided into capillary waves and gravity waves. Capillary waves, or ripples, are small, short-wavelength waves caused by weak winds affecting surface tension in calm water. They can overlap longer and larger gravity waves. How these physically complex wave types are represented in stylized video games varies depending on the respective style. Both types are usually heavily simplified in form and motion, and capillary waves are sometimes omitted entirely to reduce detail.Sea of ThievesFoam PatternsFoam patterns refer to white foam crests that form on a water surface without breaking against an obstacle or shoreline. In reality, this effect occurs when different water layers collide, and waves become steeper until their peaks collapse, and the resulting bubbles and drops scatter the sunlight. Stylized foam patterns can be found in many video game water representations and can easily be abstracted into patterns. Such patterns contribute to a cartoon look and can sometimes even replace waveforms entirely.The Legend of Zelda: The Wind WakerFoam LinesFoam lines are a very common water element in video games, represented as white graphical lines surrounding shorelines and obstacles like rocks. They typically reference two different water phenomena: foam forming around obstacles due to wave breaking, and foam along shorelines, resulting from wave breaking and the mixing of algaes with organic and artificial substances.Foam lines can have different visual appearances depending on the surface angle: The shallower the angle, the wider the foam effect. Due to the weaker waves, distinctive foam lines are rarely observed on natural lakes, but they can be included in a stylization for aesthetic purposes. Animal Crossing: New HorizonsReflectionsWhen light hits a water surface, it can either be reflectedor transmitted into the water, where it may be absorbed, scattered, or reflected back through the surface. The Fresnel effect describes the perceived balance between reflection and transmission: at steep angles, more transmitted light reaches the eye, making the water appear more translucent, while at shallow angles, increased reflection makes it appear more opaqueIn stylized video games, implementations of water reflections vary: RiME, for example, imitates the Fresnel effect but does not reflect the environment at all, only a simple, otherwise invisible cube map. Wind Waker, on the other hand, completely foregoes reflection calculations and renders a flat-shaded water surface.RiMETranslucencyAs an inhomogeneous medium, water scatters some of the transmitted light before it can be reflected back to the surface. This is why water is described as translucent rather than transparent. Some scattered light is not reflected back but absorbed, reducing intensity and shifting color toward the least absorbed wavelengths, typically blue, blue-green, or turquoise. Increased distance amplifies scattering and absorption, altering color perception. Modern real-time engines simulate these effects, including absorption-based color variation with depth. However, stylized games often simplify or omit transmission entirely, rendering water as an opaque surface.RiMERefractionAn additional aspect of water transmission is refraction, the bending of light as it transitions between air and water due to their differing densities. This causes light to bend toward the normal upon entering the water, creating the apparent distortion of submerged objects. Refraction effects also commonly appear in stylized water rendering. Kirby's Forgotten Land, for example, showcases two key visual characteristics of refraction: distortion increases with steeper viewing angles and is amplified by ripples on the water's surface.Kirby and the Forgotten LandCausticsCaustic patterns form when light rays are focused by a curved water surface, projecting bundled light patterns onto underwater surfaces or even back to surfaces above water. These patterns are influenced by the clarity of the water, the depth of the water, and the strength of the light source. They contribute greatly to the atmosphere of virtual worlds and are often found in stylized games, although only as simplistic representations.The Legend of Zelda: Ocarina of Time 3DDesign DecisionsDue to the fact that the setting of Nimue is a lake with a calm overall atmosphere, the decision was made to use very reduced gravity waves, as a calm water surface underlines this atmosphere. Capillary waves have too high a level of detail for the stylistic requirements of Nimue and were, therefore, not implemented.NimueShapesThe mood in Nimue can be summarized as calm and mystical. The design language of Nimue is graphic, rounded, and elegant. Shapes are vertically elongated and highly abstracted. Convex corners are always rounded or have a strong bevel, while concave corners are pointed to prevent the overall mass of objects from becoming too rounded.ColorsNimue uses mostly broken colors and pastels to create a serene, reflective mood and highlight the player's character with her saturated blue tones. Platforms and obstacles are depicted with a lower tonal valueto increase their visibility. Overall, the game world is kept in very unsaturated shades of blue, with the atmospheric depth, i.e., the sky and objects in the distance, falling into the complementary orange range. Shades of green and yellow are either completely avoided or extremely desaturated. The resulting reduced color palette additionally supports the atmosphere and makes it appear more harmonious.Color gamut & value/tone tests Hue, Tone & SaturationSince the color of the water, with its hue, tone, and saturation, is technically achieved by several components, a 2D mockup was first designed to more easily compare different colors in the environment. Here it could be observed that both the low and the high tonal value formed too great a contrast to the rest of the environment and thus placed an undesirable focus on the water. Therefore, the medium tone value was chosen.The hue and saturation were tested in relativity to the sky, the player character, and the background. Here, too, the color variant that harmonizes the most with the rest of the environment and contrasts the least was chosen.Foam LinesFor the design of the foam lines, we proceeded in the same way as for the color selection: In this case, a screenshot of the test scene was used as the basis for three overpaints to try out different foam lines on the stones in the scene. Version 3 offers the greatest scope in terms of movement within the patterns. Due to this, and because of the greater visual interest, we opted for variant 3. Following the mockup, the texture was prepared so that it could be technically implemented.ReflectionThe reflection of the water surface contributes to how realistic the water looks, as one would always expect a reflection with natural water, depending on the angle. However, a reflection could also contribute to the overall appearance of the water becoming less calm. The romantic character created by the reflection of diffuse light on water is more present in version 1.In addition, the soft, wafting shapes created by the reflection fit in well with the art style. A reflection is desirable, but the reflections must not take up too much focus. Ideally, the water should be lighter in tone, and the reflections should be present but less pronounced. Reflection intensityRefraction & CausticsEven though most light in our water gets absorbed, we noticed an improvement in the believability of the ground right underneath the water's surface when utilizing refraction together with the waveforms. When it comes to caustics, the diffuse lighting conditions of our scene would make visible caustic patterns physically implausible, but it felt right aesthetically, which is why we included it anyway.Technical Realization in Unreal Engine 5When building a water material in Unreal, choosing the right shading model and blend mode is crucial. While a Default Lit Translucent material with Surface Forward Shading offers the most control, it is very costly to render. The more efficient choice is the Single Layer Water shading model introduced in Unreal 4.27, which supports light absorption, scattering, reflection, refraction, and shadowing at a lower instruction count. However, there are some downsides. For example, as it only uses a single depth layer, it lacks back-face rendering, making it less suitable for underwater views. And while still quite expensive by itself, its benefits outweigh the drawbacks of our stylized water material.WaveformsStarting with the waveforms, we used panning normal maps to simulate the rather calm low-altitude gravity waves. The approach here is simple: create a wave normal map in Substance 3D Designer, sample it twice, and continuously offset the samples' UV coordinates in opposing directions at different speeds. Give one of the two samples a higher speed and normal intensity to create a sense of wind direction. This panning operation does not need to run in the fragment shader, you can move it to the vertex shader through the Vertex Interpolator without quality loss and thereby reduce the instruction count.Texture RepetitionTo reduce visible tiling, we used three simple and fairly efficient tricks. First, we offset the UVs of the Wave Samplers with a large panning noise texture to dynamically distort the wave patterns. Second, we used another sampler of that noise texture with different tiling, speed, and direction to modulate the strength of the normal maps across the surface. We sampled this noise texture four times with different variables in the material, which is a lot, but we reused them many times for most of the visual features of our water. Third, we sampled the pixel depth of the surface to mask out the waves that were far from the camera so that there were no waves in the far distance.Vertex DisplacementWhile these normal waves are enough to create the illusion of altitude on the water surface itself, they are lacking when it comes to the intersections around objects in the water, as these intersections are static without any actual vertex displacement. To fix that, two very simple sine operationswere added to drive the World Position Offset of the water mesh on the Z-axis. To keep the polycounts in check, we built a simple blueprint grid system that spawns high-res plane meshes at the center in a variable radius, and low-res plane meshes around that. This enables the culling of non-visible planes and the use of a less complex version of the water material for distant planes, where features like WPO are not needed.ColorThe general transmission amount is controlled by the opacity input of the material output, but scattering and absorption are defined via the Single Layer Water material output. The inputs Scattering Coefficients and Absorption Coefficients, which are responsible for reproducing how and how far different wavelengths travel through water, are decisive here. We use two scattering colors as parameters, which are interpolated depending on the camera distance. Close to the camera, the blue scattering colordominates, while at a distance, the orange scattering colortakes over. The advantage is a separation of the water's color from the sky's color and, thus, higher artistic control.Reflections & RefractionReflections in the Single Layer Water shading model are as usual determined by the inputs for Specularand Roughness. In our case, however, we use Lumen reflections for their accuracy and quality, and as of Unreal 5.4, the Single Layer Water model’s roughness calculation does not work with Lumen reflections. It forces mirror reflections, no matter the value input, leaving the specular lobe unaffected. Instead, it only offsets the reflection brightness, as the specular input does.For our artistic purposes, this is fine, and we do use the roughness input to fine-tune the specular level while having the specular input as the base level. A very low value was set for the specular value to keep the reflection brightness low. We further stylized the reflections by decreasing this brightness near the camera by using the already mentioned masking method via camera to interpolate between two values. For refraction, the Pixel Normal Offset mode was used, and a scalar parameter interpolates between the base refraction and the output of the normal waves.CausticsFor the caustic effect, we created a Voronoi noise pattern by using Unreal's Noise node and exporting it with a render target. In Photoshop, the pattern was duplicated twice, rotated each, colored, and blended. This texture is then projected on the objects below by using the ColorScaleBehindWater input of the Single Layer Water Material output. The pattern is dynamically distorted by adding one of the aforementioned panning noise textures to the UV coordinates.FoamlinesWe started by creating custom meshes for foam lines and applied the earlier texture pattern, but quickly realized that such a workflow would be too cumbersome and inflexible for even a small scene, so we decided to do it procedurally. Two common methods for generating intersection masks on a plane are Depth Sampling and Distance Fields. The first works by subtracting the camera's distance to the water surface at the current pixelfrom the camera's distance to the closest scene object at that pixel. The second method is to use the node "DistanceToNearestSurface" which calculates the shortest distance between a point on the water surface and the nearest object by referencing the scene's global distance field. We used both methods to control the mask width, as each alone varies with the object's surface slope, causing undesirable variations. Combining them allowed us to switch between two different mask widths, turning off "Affect Distance Field Lighting" for shallow slopes where narrower lines are wanted.The added mask of all intersections is then used for two effects to create the foam lines: "edge foam"and "edge waves". Both are shaped with the noise samplers shown above to approximate the hand-drawn foam line texture.Foam PatternsThe same noise samplers are also used to create a sparkling foam effect, loosely imitating whitecaps/foam crests to add more visual interest to the water surface. Since it only reuses operations, this effect is very cheap. Similarly, the wave normals are used to create something like fake subsurface scattering to further distinguish the moving water surface. Interactive RipplesA third type of foam is added as interactive waves that ripple around the player character when walking through shallow water. This is done through a Render Target and particles, as demonstrated in this Unity tutorial by Minions Art. The steps described there are all easily applicable in Unreal with a Niagara System, a little Blueprint work, and common material nodes. We added a Height to Normal conversion for better visual integration into our existing wave setup. Finally, here are all those operations combined for the material inputs:NimueBest PracticesUse Single Layer Water for efficient translucency, but note it lacks back-face rendering and forces mirror reflections with Lumen;For simple low-altitude waves, pan two offset samples of a normal map at different speeds; move panning to Vertex Shader for better performance;Break up texture tiling efficiently by offsetting UVs with a large panning noise, modulating normal strength, and fading distant waves using pixel depth;Sampling one small noise texture at different scales can power this and many other features of a water shader efficiently;If high-altitude waves aren't needed, a simple sine-based WPO can suffice for vertex displacement; implement a grid system for LODs and culling of subdivided water meshes;Blend two scattering colors by camera distance for artistic watercolor control and separation from sky reflections;Combining depth sampling and distance fields to derive the foam lines allows for more flexible intersection widths but comes at a higher cost. Further ResourcesHere are some resources that helped us in the shader creation process:General shader theory and creation: tharlevfx, Ben Cloward;Interactive water in Unity: Minions Art;Another free stylized water material in Unreal by Fabian Lopez Arosa;Technical art wizardry: Ghislain Girardot.ConclusionWe hope this breakdown of our water material creation process will help you in your projects.If you want to take a look at our shader yourself or even use it for your own game projects, you can download the complete setup on Gumroad. We look forward to seeing your water shaders and exchanging ideas. Feel free to reach out if you have any questions or want to connect.Kolja Bopp, Academic SupervisorLeanna Geideck, Concept ArtistStephan zu Münster, Technical Artist #how #build #stylized #water #shader
    80.LV
    How To Build Stylized Water Shader: Design & Implementation For Nimue
    NimueIntroductionFor three semesters, our student team has been hard at work on the prototype for Nimue, a 3D platformer in which you play an enchanted princess who lost her memories. She needs to find her way through the castle ruins on a misty lake to uncover her past. Water is a visual core element of this game prototype, so we took extra care in its development. In this article, we will take an in-depth look at the design and technical implementation of a lake water material.The first prototype of Nimue can be played on itch.io soon. A link to our shader for use in your own projects can be found at the end of this article.Taxonomy of WaterBefore we dive into the design decisions and technical implementation, we present a simplified taxonomy of visual water components to better understand the requirements of its representation:RiMEWind WavesWaves generated by wind, which form on an open water surface, can be divided into capillary waves and gravity waves. Capillary waves, or ripples, are small, short-wavelength waves caused by weak winds affecting surface tension in calm water. They can overlap longer and larger gravity waves. How these physically complex wave types are represented in stylized video games varies depending on the respective style. Both types are usually heavily simplified in form and motion, and capillary waves are sometimes omitted entirely to reduce detail.Sea of ThievesFoam PatternsFoam patterns refer to white foam crests that form on a water surface without breaking against an obstacle or shoreline. In reality, this effect occurs when different water layers collide, and waves become steeper until their peaks collapse, and the resulting bubbles and drops scatter the sunlight. Stylized foam patterns can be found in many video game water representations and can easily be abstracted into patterns. Such patterns contribute to a cartoon look and can sometimes even replace waveforms entirely.The Legend of Zelda: The Wind WakerFoam LinesFoam lines are a very common water element in video games, represented as white graphical lines surrounding shorelines and obstacles like rocks. They typically reference two different water phenomena: foam forming around obstacles due to wave breaking, and foam along shorelines, resulting from wave breaking and the mixing of algaes with organic and artificial substances.Foam lines can have different visual appearances depending on the surface angle: The shallower the angle, the wider the foam effect. Due to the weaker waves, distinctive foam lines are rarely observed on natural lakes, but they can be included in a stylization for aesthetic purposes. Animal Crossing: New HorizonsReflectionsWhen light hits a water surface, it can either be reflected (specular reflection) or transmitted into the water, where it may be absorbed, scattered, or reflected back through the surface. The Fresnel effect describes the perceived balance between reflection and transmission: at steep angles, more transmitted light reaches the eye, making the water appear more translucent, while at shallow angles, increased reflection makes it appear more opaqueIn stylized video games, implementations of water reflections vary: RiME, for example, imitates the Fresnel effect but does not reflect the environment at all, only a simple, otherwise invisible cube map. Wind Waker, on the other hand, completely foregoes reflection calculations and renders a flat-shaded water surface.RiMETranslucencyAs an inhomogeneous medium, water scatters some of the transmitted light before it can be reflected back to the surface. This is why water is described as translucent rather than transparent. Some scattered light is not reflected back but absorbed, reducing intensity and shifting color toward the least absorbed wavelengths, typically blue, blue-green, or turquoise. Increased distance amplifies scattering and absorption, altering color perception. Modern real-time engines simulate these effects, including absorption-based color variation with depth. However, stylized games often simplify or omit transmission entirely, rendering water as an opaque surface.RiMERefractionAn additional aspect of water transmission is refraction, the bending of light as it transitions between air and water due to their differing densities. This causes light to bend toward the normal upon entering the water, creating the apparent distortion of submerged objects. Refraction effects also commonly appear in stylized water rendering. Kirby's Forgotten Land, for example, showcases two key visual characteristics of refraction: distortion increases with steeper viewing angles and is amplified by ripples on the water's surface.Kirby and the Forgotten LandCausticsCaustic patterns form when light rays are focused by a curved water surface (caused by waves and ripples), projecting bundled light patterns onto underwater surfaces or even back to surfaces above water. These patterns are influenced by the clarity of the water, the depth of the water, and the strength of the light source. They contribute greatly to the atmosphere of virtual worlds and are often found in stylized games, although only as simplistic representations.The Legend of Zelda: Ocarina of Time 3DDesign DecisionsDue to the fact that the setting of Nimue is a lake with a calm overall atmosphere, the decision was made to use very reduced gravity waves, as a calm water surface underlines this atmosphere. Capillary waves have too high a level of detail for the stylistic requirements of Nimue and were, therefore, not implemented.NimueShapesThe mood in Nimue can be summarized as calm and mystical. The design language of Nimue is graphic, rounded, and elegant. Shapes are vertically elongated and highly abstracted. Convex corners are always rounded or have a strong bevel, while concave corners are pointed to prevent the overall mass of objects from becoming too rounded.ColorsNimue uses mostly broken colors and pastels to create a serene, reflective mood and highlight the player's character with her saturated blue tones. Platforms and obstacles are depicted with a lower tonal value (darker) to increase their visibility. Overall, the game world is kept in very unsaturated shades of blue, with the atmospheric depth, i.e., the sky and objects in the distance, falling into the complementary orange range. Shades of green and yellow are either completely avoided or extremely desaturated. The resulting reduced color palette additionally supports the atmosphere and makes it appear more harmonious.Color gamut & value/tone tests Hue, Tone & SaturationSince the color of the water, with its hue, tone, and saturation, is technically achieved by several components, a 2D mockup was first designed to more easily compare different colors in the environment. Here it could be observed that both the low and the high tonal value formed too great a contrast to the rest of the environment and thus placed an undesirable focus on the water. Therefore, the medium tone value was chosen.The hue and saturation were tested in relativity to the sky, the player character, and the background. Here, too, the color variant that harmonizes the most with the rest of the environment and contrasts the least was chosen.Foam LinesFor the design of the foam lines, we proceeded in the same way as for the color selection: In this case, a screenshot of the test scene was used as the basis for three overpaints to try out different foam lines on the stones in the scene. Version 3 offers the greatest scope in terms of movement within the patterns. Due to this, and because of the greater visual interest, we opted for variant 3. Following the mockup, the texture was prepared so that it could be technically implemented.ReflectionThe reflection of the water surface contributes to how realistic the water looks, as one would always expect a reflection with natural water, depending on the angle. However, a reflection could also contribute to the overall appearance of the water becoming less calm. The romantic character created by the reflection of diffuse light on water is more present in version 1.In addition, the soft, wafting shapes created by the reflection fit in well with the art style. A reflection is desirable, but the reflections must not take up too much focus. Ideally, the water should be lighter in tone, and the reflections should be present but less pronounced. Reflection intensityRefraction & CausticsEven though most light in our water gets absorbed, we noticed an improvement in the believability of the ground right underneath the water's surface when utilizing refraction together with the waveforms. When it comes to caustics, the diffuse lighting conditions of our scene would make visible caustic patterns physically implausible, but it felt right aesthetically, which is why we included it anyway (not being bound to physical plausibility is one of the perks of stylized graphics).Technical Realization in Unreal Engine 5When building a water material in Unreal, choosing the right shading model and blend mode is crucial. While a Default Lit Translucent material with Surface Forward Shading offers the most control, it is very costly to render. The more efficient choice is the Single Layer Water shading model introduced in Unreal 4.27, which supports light absorption, scattering, reflection, refraction, and shadowing at a lower instruction count. However, there are some downsides. For example, as it only uses a single depth layer, it lacks back-face rendering, making it less suitable for underwater views. And while still quite expensive by itself, its benefits outweigh the drawbacks of our stylized water material.WaveformsStarting with the waveforms, we used panning normal maps to simulate the rather calm low-altitude gravity waves. The approach here is simple: create a wave normal map in Substance 3D Designer, sample it twice, and continuously offset the samples' UV coordinates in opposing directions at different speeds. Give one of the two samples a higher speed and normal intensity to create a sense of wind direction. This panning operation does not need to run in the fragment shader, you can move it to the vertex shader through the Vertex Interpolator without quality loss and thereby reduce the instruction count.Texture RepetitionTo reduce visible tiling, we used three simple and fairly efficient tricks. First, we offset the UVs of the Wave Samplers with a large panning noise texture to dynamically distort the wave patterns. Second, we used another sampler of that noise texture with different tiling, speed, and direction to modulate the strength of the normal maps across the surface. We sampled this noise texture four times with different variables in the material, which is a lot, but we reused them many times for most of the visual features of our water. Third, we sampled the pixel depth of the surface to mask out the waves that were far from the camera so that there were no waves in the far distance.Vertex DisplacementWhile these normal waves are enough to create the illusion of altitude on the water surface itself, they are lacking when it comes to the intersections around objects in the water, as these intersections are static without any actual vertex displacement. To fix that, two very simple sine operations (one along the X-axis and the other on the Y-axis) were added to drive the World Position Offset of the water mesh on the Z-axis. To keep the polycounts in check, we built a simple blueprint grid system that spawns high-res plane meshes at the center in a variable radius, and low-res plane meshes around that. This enables the culling of non-visible planes and the use of a less complex version of the water material for distant planes, where features like WPO are not needed.ColorThe general transmission amount is controlled by the opacity input of the material output, but scattering and absorption are defined via the Single Layer Water material output. The inputs Scattering Coefficients and Absorption Coefficients, which are responsible for reproducing how and how far different wavelengths travel through water, are decisive here. We use two scattering colors as parameters, which are interpolated depending on the camera distance. Close to the camera, the blue scattering color (ScatteringColorNear) dominates, while at a distance, the orange scattering color (ScatteringColorFar) takes over. The advantage is a separation of the water's color from the sky's color and, thus, higher artistic control.Reflections & RefractionReflections in the Single Layer Water shading model are as usual determined by the inputs for Specular (reflection intensity) and Roughness (reflection diffusion). In our case, however, we use Lumen reflections for their accuracy and quality, and as of Unreal 5.4, the Single Layer Water model’s roughness calculation does not work with Lumen reflections. It forces mirror reflections (Roughness = 0), no matter the value input, leaving the specular lobe unaffected. Instead, it only offsets the reflection brightness, as the specular input does.For our artistic purposes, this is fine, and we do use the roughness input to fine-tune the specular level while having the specular input as the base level. A very low value was set for the specular value to keep the reflection brightness low. We further stylized the reflections by decreasing this brightness near the camera by using the already mentioned masking method via camera to interpolate between two values (RoughnessNear and RoughnessFar). For refraction, the Pixel Normal Offset mode was used, and a scalar parameter interpolates between the base refraction and the output of the normal waves.CausticsFor the caustic effect, we created a Voronoi noise pattern by using Unreal's Noise node and exporting it with a render target. In Photoshop, the pattern was duplicated twice, rotated each, colored, and blended. This texture is then projected on the objects below by using the ColorScaleBehindWater input of the Single Layer Water Material output. The pattern is dynamically distorted by adding one of the aforementioned panning noise textures to the UV coordinates.FoamlinesWe started by creating custom meshes for foam lines and applied the earlier texture pattern, but quickly realized that such a workflow would be too cumbersome and inflexible for even a small scene, so we decided to do it procedurally. Two common methods for generating intersection masks on a plane are Depth Sampling and Distance Fields. The first works by subtracting the camera's distance to the water surface at the current pixel (i.e., the "PixelDepth") from the camera's distance to the closest scene object at that pixel (i.e., the "SceneDepth"). The second method is to use the node "DistanceToNearestSurface" which calculates the shortest distance between a point on the water surface and the nearest object by referencing the scene's global distance field. We used both methods to control the mask width, as each alone varies with the object's surface slope, causing undesirable variations. Combining them allowed us to switch between two different mask widths, turning off "Affect Distance Field Lighting" for shallow slopes where narrower lines are wanted.The added mask of all intersections is then used for two effects to create the foam lines: "edge foam" (that does not depart from the intersection) and "edge waves" (which go outwards from the edge foam). Both are shaped with the noise samplers shown above to approximate the hand-drawn foam line texture.Foam PatternsThe same noise samplers are also used to create a sparkling foam effect, loosely imitating whitecaps/foam crests to add more visual interest to the water surface. Since it only reuses operations, this effect is very cheap. Similarly, the wave normals are used to create something like fake subsurface scattering to further distinguish the moving water surface. Interactive RipplesA third type of foam is added as interactive waves that ripple around the player character when walking through shallow water. This is done through a Render Target and particles, as demonstrated in this Unity tutorial by Minions Art. The steps described there are all easily applicable in Unreal with a Niagara System, a little Blueprint work, and common material nodes. We added a Height to Normal conversion for better visual integration into our existing wave setup. Finally, here are all those operations combined for the material inputs:NimueBest PracticesUse Single Layer Water for efficient translucency, but note it lacks back-face rendering and forces mirror reflections with Lumen;For simple low-altitude waves, pan two offset samples of a normal map at different speeds; move panning to Vertex Shader for better performance;Break up texture tiling efficiently by offsetting UVs with a large panning noise, modulating normal strength, and fading distant waves using pixel depth;Sampling one small noise texture at different scales can power this and many other features of a water shader efficiently;If high-altitude waves aren't needed, a simple sine-based WPO can suffice for vertex displacement; implement a grid system for LODs and culling of subdivided water meshes;Blend two scattering colors by camera distance for artistic watercolor control and separation from sky reflections;Combining depth sampling and distance fields to derive the foam lines allows for more flexible intersection widths but comes at a higher cost. Further ResourcesHere are some resources that helped us in the shader creation process:General shader theory and creation: tharlevfx, Ben Cloward;Interactive water in Unity: Minions Art;Another free stylized water material in Unreal by Fabian Lopez Arosa;Technical art wizardry: Ghislain Girardot.ConclusionWe hope this breakdown of our water material creation process will help you in your projects.If you want to take a look at our shader yourself or even use it for your own game projects, you can download the complete setup on Gumroad. We look forward to seeing your water shaders and exchanging ideas. Feel free to reach out if you have any questions or want to connect.Kolja Bopp, Academic SupervisorLeanna Geideck, Concept ArtistStephan zu Münster, Technical Artist
    0 Commentarios 0 Acciones
  • #333;">These Vegetables Require Less Water Than Most
    Everything is more expensive this year, and that likely includes utilities like your water bill.
    While growing vegetables in your yard can be enchanting and empowering, it isn’t very efficient (compared to farms) in terms of water usage.
    There are a number of ways to become more efficient and sustainable, including using drip irrigation, but another way is to only plant vegetables that don't need too much water to begin with.
    Watering at the root is keyBefore I get to the specific vegetables, it's important to go over a few general watering tips.Remember that vegetables get hydration through their roots, which live underground.
    Watering from above, like a hose or sprinkler, has problems: you’re getting the plants wet more than the roots, which creates conditions for disease spread; you’re watering less precisely, therefore wasting water; and the impact of the water against the dirt causes droplets to bounce back up with whatever fungus or viruses are in the dirt, also spreading disease.
    Watering gently and consistently at ground level with drip irrigation is the best option for both the plant and your wallet. To ensure you’re watering efficiently, group plants with similar watering needs together in your garden, so you can set the drip appropriately to water less. But even more important is remembering that roots grow over time.
    A new seedling has shallow roots, whereas an end-of-season plant has deeply established roots.
    More roots means that the plant can absorb more water from deeper underground.
    Less roots means less hydration from the soil, so more water is needed at a shallower depth.
    (Though some vegetables, like corn and lettuce, will always be shallow rooted, and thus aren’t good candidates for less water.)Hothouse plantsAccording to Oregon State University, a tomato plant's need for watering is negated by the deep roots the plants establish over the season.
    As above, you want to water sufficiently early in the season as roots are established while taking care not to over water, which will result in those roots staying close to the surface.
    If the plant needs water, those roots will grow deeper in search of moisture.
    Reducing water greatly, if not cutting it off entirely mid-season, shouldn’t harm your harvest.
    The lack of surface water will reduce disease spread, and tomatoes will ripen if you reduce their watering.
    It’s not only tomatoes, either: Squash, which includes zucchini, summer and winter squash, as well as melons, eggplants, and hot peppers all behave the same in terms of water needs and roots. Beans





    Credit: Amanda Blum


    Most beans, particularly pole beans, have adapted to drought conditions over time.
    As such, they can survive and produce flowers and fruit with minimal moisture.
    Beans require water to germinate, so if you direct sow, ensure the seeds have consistent moisture levels.
    Once germinated, you can reduce (but not eliminate) water.
    Since beans have such a short season (usually 60 days or less), they require less water simply by existing for less time.
    Less moisture is going to reduce common bean problems like powdery mildew, a quickly spreading surface fungus.Chard and okra





    Credit: Amanda Blum


    For some heat hardier vegetables like chard and okra, they still require water, but do better with weekly or every-other-weekly deep watering, as opposed to daily drip.
    Okra is native to drier climates and prefers less water.
    The deep roots of the plant allow it to draw enough water from the soil to sustain itself.
    Chard and kale can use their huge leaves to shade the ground, which is an effective form of moisture retention.
    Occasional deep waterings will be enough for the plant to continue growing.Blueberries prefer less moistureI know, blueberries are a fruit and not a vegetable, but I felt compelled to include the advice here anyway.
    Consider it a bonus tip.
    A few years ago, Micah Geiselman, a blueberry farmer from Morning Shade Farm in Canby came to inspect my many bushes, and he had surprising advice: “People over-water their blueberries,” he explained to me.
    They appreciate good drainage and do better with less water. I’ve since changed the elevation of my blueberries to ensure better drainage and moved watering lines further away—the results were astounding.
    I experienced better yields, but the berries themselves were plumper and better tasting.
    This isn’t conclusive, of course, since there are too many variables to account for, but I take the advice of a blueberry expert seriously. 
    #666;">المصدر: https://lifehacker.com/home/these-vegetables-require-less-water?utm_medium=RSS" style="color: #0066cc; text-decoration: none;">lifehacker.com
    #0066cc;">#these #vegetables #require #less #water #than #most #everything #more #expensive #this #year #and #that #likely #includes #utilities #like #your #billwhile #growing #yard #can #enchanting #empowering #isnt #very #efficient #compared #farms #terms #usagethere #are #number #ways #become #sustainable #including #using #drip #irrigation #but #another #way #only #plant #don039t #need #too #much #begin #withwatering #the #root #keybefore #get #specific #it039s #important #over #few #general #watering #tipsremember #hydration #through #their #roots #which #live #undergroundwatering #from #above #hose #sprinkler #has #problems #youre #getting #plants #wet #creates #conditions #for #disease #spread #precisely #therefore #wasting #impact #against #dirt #causes #droplets #bounce #back #with #whatever #fungus #viruses #also #spreading #diseasewatering #gently #consistently #ground #level #best #option #both #walletto #ensure #efficiently #group #similar #needs #together #garden #you #set #appropriately #lessbut #even #remembering #grow #timea #new #seedling #shallow #whereas #endofseason #deeply #established #rootsmore #means #absorb #deeper #undergroundless #soil #needed #shallower #depththough #some #corn #lettuce #will #always #rooted #thus #arent #good #candidates #waterhothouse #plantsaccording #oregon #state #university #tomato #plant039s #negated #deep #establish #seasonas #want #sufficiently #early #season #while #taking #care #not #result #those #staying #close #surfaceif #search #moisturereducing #greatly #cutting #off #entirely #midseason #shouldnt #harm #harvestthe #lack #surface #reduce #tomatoes #ripen #wateringits #either #squash #zucchini #summer #winter #well #melons #eggplants #hot #peppers #all #behave #same #rootsbeans #credit #amanda #blum #beans #particularly #pole #have #adapted #drought #timeas #such #they #survive #produce #flowers #fruit #minimal #moisturebeans #germinate #direct #sow #seeds #consistent #moisture #levelsonce #germinated #eliminate #watersince #short #usually #days #simply #existing #timeless #going #common #bean #powdery #mildew #quickly #funguschard #okra #heat #hardier #chard #still #better #weekly #everyotherweekly #opposed #daily #dripokra #native #drier #climates #prefers #waterthe #allow #draw #enough #sustain #itselfchard #kale #use #huge #leaves #shade #effective #form #retentionoccasional #waterings #continue #growingblueberries #prefer #moisturei #know #blueberries #vegetable #felt #compelled #include #advice #here #anywayconsider #bonus #tipa #years #ago #micah #geiselman #blueberry #farmer #morning #farm #canby #came #inspect #many #bushes #had #surprising #people #overwater #explained #methey #appreciate #drainage #waterive #since #changed #elevation #moved #lines #further #awaythe #results #were #astoundingi #experienced #yields #berries #themselves #plumper #tastingthis #conclusive #course #there #variables #account #take #expert #seriously
    These Vegetables Require Less Water Than Most
    Everything is more expensive this year, and that likely includes utilities like your water bill. While growing vegetables in your yard can be enchanting and empowering, it isn’t very efficient (compared to farms) in terms of water usage. There are a number of ways to become more efficient and sustainable, including using drip irrigation, but another way is to only plant vegetables that don't need too much water to begin with. Watering at the root is keyBefore I get to the specific vegetables, it's important to go over a few general watering tips.Remember that vegetables get hydration through their roots, which live underground. Watering from above, like a hose or sprinkler, has problems: you’re getting the plants wet more than the roots, which creates conditions for disease spread; you’re watering less precisely, therefore wasting water; and the impact of the water against the dirt causes droplets to bounce back up with whatever fungus or viruses are in the dirt, also spreading disease. Watering gently and consistently at ground level with drip irrigation is the best option for both the plant and your wallet. To ensure you’re watering efficiently, group plants with similar watering needs together in your garden, so you can set the drip appropriately to water less. But even more important is remembering that roots grow over time. A new seedling has shallow roots, whereas an end-of-season plant has deeply established roots. More roots means that the plant can absorb more water from deeper underground. Less roots means less hydration from the soil, so more water is needed at a shallower depth. (Though some vegetables, like corn and lettuce, will always be shallow rooted, and thus aren’t good candidates for less water.)Hothouse plantsAccording to Oregon State University, a tomato plant's need for watering is negated by the deep roots the plants establish over the season. As above, you want to water sufficiently early in the season as roots are established while taking care not to over water, which will result in those roots staying close to the surface. If the plant needs water, those roots will grow deeper in search of moisture. Reducing water greatly, if not cutting it off entirely mid-season, shouldn’t harm your harvest. The lack of surface water will reduce disease spread, and tomatoes will ripen if you reduce their watering. It’s not only tomatoes, either: Squash, which includes zucchini, summer and winter squash, as well as melons, eggplants, and hot peppers all behave the same in terms of water needs and roots. Beans Credit: Amanda Blum Most beans, particularly pole beans, have adapted to drought conditions over time. As such, they can survive and produce flowers and fruit with minimal moisture. Beans require water to germinate, so if you direct sow, ensure the seeds have consistent moisture levels. Once germinated, you can reduce (but not eliminate) water. Since beans have such a short season (usually 60 days or less), they require less water simply by existing for less time. Less moisture is going to reduce common bean problems like powdery mildew, a quickly spreading surface fungus.Chard and okra Credit: Amanda Blum For some heat hardier vegetables like chard and okra, they still require water, but do better with weekly or every-other-weekly deep watering, as opposed to daily drip. Okra is native to drier climates and prefers less water. The deep roots of the plant allow it to draw enough water from the soil to sustain itself. Chard and kale can use their huge leaves to shade the ground, which is an effective form of moisture retention. Occasional deep waterings will be enough for the plant to continue growing.Blueberries prefer less moistureI know, blueberries are a fruit and not a vegetable, but I felt compelled to include the advice here anyway. Consider it a bonus tip. A few years ago, Micah Geiselman, a blueberry farmer from Morning Shade Farm in Canby came to inspect my many bushes, and he had surprising advice: “People over-water their blueberries,” he explained to me. They appreciate good drainage and do better with less water. I’ve since changed the elevation of my blueberries to ensure better drainage and moved watering lines further away—the results were astounding. I experienced better yields, but the berries themselves were plumper and better tasting. This isn’t conclusive, of course, since there are too many variables to account for, but I take the advice of a blueberry expert seriously. 
    المصدر: lifehacker.com
    #these #vegetables #require #less #water #than #most #everything #more #expensive #this #year #and #that #likely #includes #utilities #like #your #billwhile #growing #yard #can #enchanting #empowering #isnt #very #efficient #compared #farms #terms #usagethere #are #number #ways #become #sustainable #including #using #drip #irrigation #but #another #way #only #plant #don039t #need #too #much #begin #withwatering #the #root #keybefore #get #specific #it039s #important #over #few #general #watering #tipsremember #hydration #through #their #roots #which #live #undergroundwatering #from #above #hose #sprinkler #has #problems #youre #getting #plants #wet #creates #conditions #for #disease #spread #precisely #therefore #wasting #impact #against #dirt #causes #droplets #bounce #back #with #whatever #fungus #viruses #also #spreading #diseasewatering #gently #consistently #ground #level #best #option #both #walletto #ensure #efficiently #group #similar #needs #together #garden #you #set #appropriately #lessbut #even #remembering #grow #timea #new #seedling #shallow #whereas #endofseason #deeply #established #rootsmore #means #absorb #deeper #undergroundless #soil #needed #shallower #depththough #some #corn #lettuce #will #always #rooted #thus #arent #good #candidates #waterhothouse #plantsaccording #oregon #state #university #tomato #plant039s #negated #deep #establish #seasonas #want #sufficiently #early #season #while #taking #care #not #result #those #staying #close #surfaceif #search #moisturereducing #greatly #cutting #off #entirely #midseason #shouldnt #harm #harvestthe #lack #surface #reduce #tomatoes #ripen #wateringits #either #squash #zucchini #summer #winter #well #melons #eggplants #hot #peppers #all #behave #same #rootsbeans #credit #amanda #blum #beans #particularly #pole #have #adapted #drought #timeas #such #they #survive #produce #flowers #fruit #minimal #moisturebeans #germinate #direct #sow #seeds #consistent #moisture #levelsonce #germinated #eliminate #watersince #short #usually #days #simply #existing #timeless #going #common #bean #powdery #mildew #quickly #funguschard #okra #heat #hardier #chard #still #better #weekly #everyotherweekly #opposed #daily #dripokra #native #drier #climates #prefers #waterthe #allow #draw #enough #sustain #itselfchard #kale #use #huge #leaves #shade #effective #form #retentionoccasional #waterings #continue #growingblueberries #prefer #moisturei #know #blueberries #vegetable #felt #compelled #include #advice #here #anywayconsider #bonus #tipa #years #ago #micah #geiselman #blueberry #farmer #morning #farm #canby #came #inspect #many #bushes #had #surprising #people #overwater #explained #methey #appreciate #drainage #waterive #since #changed #elevation #moved #lines #further #awaythe #results #were #astoundingi #experienced #yields #berries #themselves #plumper #tastingthis #conclusive #course #there #variables #account #take #expert #seriously
    LIFEHACKER.COM
    These Vegetables Require Less Water Than Most
    Everything is more expensive this year, and that likely includes utilities like your water bill. While growing vegetables in your yard can be enchanting and empowering, it isn’t very efficient (compared to farms) in terms of water usage. There are a number of ways to become more efficient and sustainable, including using drip irrigation, but another way is to only plant vegetables that don't need too much water to begin with. Watering at the root is keyBefore I get to the specific vegetables, it's important to go over a few general watering tips.Remember that vegetables get hydration through their roots, which live underground. Watering from above, like a hose or sprinkler, has problems: you’re getting the plants wet more than the roots, which creates conditions for disease spread; you’re watering less precisely, therefore wasting water; and the impact of the water against the dirt causes droplets to bounce back up with whatever fungus or viruses are in the dirt, also spreading disease. Watering gently and consistently at ground level with drip irrigation is the best option for both the plant and your wallet. To ensure you’re watering efficiently, group plants with similar watering needs together in your garden, so you can set the drip appropriately to water less. But even more important is remembering that roots grow over time. A new seedling has shallow roots, whereas an end-of-season plant has deeply established roots. More roots means that the plant can absorb more water from deeper underground. Less roots means less hydration from the soil, so more water is needed at a shallower depth. (Though some vegetables, like corn and lettuce, will always be shallow rooted, and thus aren’t good candidates for less water.)Hothouse plantsAccording to Oregon State University, a tomato plant's need for watering is negated by the deep roots the plants establish over the season. As above, you want to water sufficiently early in the season as roots are established while taking care not to over water, which will result in those roots staying close to the surface. If the plant needs water, those roots will grow deeper in search of moisture. Reducing water greatly, if not cutting it off entirely mid-season, shouldn’t harm your harvest. The lack of surface water will reduce disease spread, and tomatoes will ripen if you reduce their watering. It’s not only tomatoes, either: Squash, which includes zucchini, summer and winter squash, as well as melons, eggplants, and hot peppers all behave the same in terms of water needs and roots. Beans Credit: Amanda Blum Most beans, particularly pole beans, have adapted to drought conditions over time. As such, they can survive and produce flowers and fruit with minimal moisture. Beans require water to germinate, so if you direct sow, ensure the seeds have consistent moisture levels. Once germinated, you can reduce (but not eliminate) water. Since beans have such a short season (usually 60 days or less), they require less water simply by existing for less time. Less moisture is going to reduce common bean problems like powdery mildew, a quickly spreading surface fungus.Chard and okra Credit: Amanda Blum For some heat hardier vegetables like chard and okra, they still require water, but do better with weekly or every-other-weekly deep watering, as opposed to daily drip. Okra is native to drier climates and prefers less water. The deep roots of the plant allow it to draw enough water from the soil to sustain itself. Chard and kale can use their huge leaves to shade the ground, which is an effective form of moisture retention. Occasional deep waterings will be enough for the plant to continue growing.Blueberries prefer less moistureI know, blueberries are a fruit and not a vegetable, but I felt compelled to include the advice here anyway. Consider it a bonus tip. A few years ago, Micah Geiselman, a blueberry farmer from Morning Shade Farm in Canby came to inspect my many bushes, and he had surprising advice: “People over-water their blueberries,” he explained to me. They appreciate good drainage and do better with less water. I’ve since changed the elevation of my blueberries to ensure better drainage and moved watering lines further away—the results were astounding. I experienced better yields, but the berries themselves were plumper and better tasting. This isn’t conclusive, of course, since there are too many variables to account for, but I take the advice of a blueberry expert seriously. 
    0 Commentarios 0 Acciones
  • Nintendo Switch 2 Final Fantasy VII Remake Unlikely to Feature 60 FPS Mode, Despite Recent Hints; Part 3 Switch 2 Port May Prevent Jump to Unreal Engine 5













    The Nintendo Switch 2 version of Final Fantasy VII Remake is unlikely to feature a 60 FPS mode, despite indications found in recent footage.
    During the latest episode of their weekly podcast, the tech experts at Digital Foundry took a good look at the new game footage that was featured in a recent Creator's Voice video, comparing it to footage captured on PlayStation 5 in Performance Mode, highlighting the differences between the two versions of the game. Despite a blurrier image, heavier dithering on hair, and shallower depth of field, the Nintendo Switch 2 version of the game holds up quite well.
    What Final Fantasy VII Remake is unlikely to offer on Nintendo Switch 2, as opposed to PlayStation 5, is a 60 FPS mode. In the Creator's Voice video, the iconic scene with Cloud jumping off the train right before beginning the mission to destroy Reactor No.1 runs at 60 FPS, which suggested the Nintendo Switch 2 version would offer a 60 FPS option, but in their analysis, Digital Foundry highlighted how the quality of Cloud's hair in the shot is even higher than in the same sequence on PlayStation 5 in Performance Mode, so the footage was not taken from the Switch 2 version, but likely from the PC version.
    In the aforementioned Creator's Voice video, Final Fantasy VII Remake director Naoki Hamaguchi hinted that the entire remake trilogy could be coming to Nintendo Switch 2. According to Digital Foundry, this intention could suggest that the yet-to-be-announced third part of the trilogy may not make the jump to Unreal Engine 5 as, while the engine could solve some of the visual issues we have seen in Final Fantasy VII Rebirth, we currently have no indication that the engine can run well on the system, or that visuals could be cut down significantly to make the game run on the system and still look reasonably good.  With the developer's desire to have part 3 out as soon as possible, which would be difficult to accomplish with an engine change, this statement could have provided an indication of the next game's technical direction.
    Final Fantasy VII Remake launches on Nintendo Switch 2 on a yet to be confirmed release date.


    Deal of the Day





















    المصدر: https://wccftech.com/final-fantasy-vii-remake-nintendo-switch-2-no-60-fps-mode-unreal-engine-5/
    Nintendo Switch 2 Final Fantasy VII Remake Unlikely to Feature 60 FPS Mode, Despite Recent Hints; Part 3 Switch 2 Port May Prevent Jump to Unreal Engine 5
    The Nintendo Switch 2 version of Final Fantasy VII Remake is unlikely to feature a 60 FPS mode, despite indications found in recent footage. During the latest episode of their weekly podcast, the tech experts at Digital Foundry took a good look at the new game footage that was featured in a recent Creator's Voice video, comparing it to footage captured on PlayStation 5 in Performance Mode, highlighting the differences between the two versions of the game. Despite a blurrier image, heavier dithering on hair, and shallower depth of field, the Nintendo Switch 2 version of the game holds up quite well. What Final Fantasy VII Remake is unlikely to offer on Nintendo Switch 2, as opposed to PlayStation 5, is a 60 FPS mode. In the Creator's Voice video, the iconic scene with Cloud jumping off the train right before beginning the mission to destroy Reactor No.1 runs at 60 FPS, which suggested the Nintendo Switch 2 version would offer a 60 FPS option, but in their analysis, Digital Foundry highlighted how the quality of Cloud's hair in the shot is even higher than in the same sequence on PlayStation 5 in Performance Mode, so the footage was not taken from the Switch 2 version, but likely from the PC version. In the aforementioned Creator's Voice video, Final Fantasy VII Remake director Naoki Hamaguchi hinted that the entire remake trilogy could be coming to Nintendo Switch 2. According to Digital Foundry, this intention could suggest that the yet-to-be-announced third part of the trilogy may not make the jump to Unreal Engine 5 as, while the engine could solve some of the visual issues we have seen in Final Fantasy VII Rebirth, we currently have no indication that the engine can run well on the system, or that visuals could be cut down significantly to make the game run on the system and still look reasonably good.  With the developer's desire to have part 3 out as soon as possible, which would be difficult to accomplish with an engine change, this statement could have provided an indication of the next game's technical direction. Final Fantasy VII Remake launches on Nintendo Switch 2 on a yet to be confirmed release date. Deal of the Day المصدر: https://wccftech.com/final-fantasy-vii-remake-nintendo-switch-2-no-60-fps-mode-unreal-engine-5/
    WCCFTECH.COM
    Nintendo Switch 2 Final Fantasy VII Remake Unlikely to Feature 60 FPS Mode, Despite Recent Hints; Part 3 Switch 2 Port May Prevent Jump to Unreal Engine 5
    The Nintendo Switch 2 version of Final Fantasy VII Remake is unlikely to feature a 60 FPS mode, despite indications found in recent footage. During the latest episode of their weekly podcast, the tech experts at Digital Foundry took a good look at the new game footage that was featured in a recent Creator's Voice video, comparing it to footage captured on PlayStation 5 in Performance Mode, highlighting the differences between the two versions of the game. Despite a blurrier image, heavier dithering on hair, and shallower depth of field, the Nintendo Switch 2 version of the game holds up quite well. What Final Fantasy VII Remake is unlikely to offer on Nintendo Switch 2, as opposed to PlayStation 5, is a 60 FPS mode. In the Creator's Voice video, the iconic scene with Cloud jumping off the train right before beginning the mission to destroy Reactor No.1 runs at 60 FPS, which suggested the Nintendo Switch 2 version would offer a 60 FPS option, but in their analysis, Digital Foundry highlighted how the quality of Cloud's hair in the shot is even higher than in the same sequence on PlayStation 5 in Performance Mode, so the footage was not taken from the Switch 2 version, but likely from the PC version. In the aforementioned Creator's Voice video, Final Fantasy VII Remake director Naoki Hamaguchi hinted that the entire remake trilogy could be coming to Nintendo Switch 2. According to Digital Foundry, this intention could suggest that the yet-to-be-announced third part of the trilogy may not make the jump to Unreal Engine 5 as, while the engine could solve some of the visual issues we have seen in Final Fantasy VII Rebirth, we currently have no indication that the engine can run well on the system, or that visuals could be cut down significantly to make the game run on the system and still look reasonably good.  With the developer's desire to have part 3 out as soon as possible, which would be difficult to accomplish with an engine change, this statement could have provided an indication of the next game's technical direction. Final Fantasy VII Remake launches on Nintendo Switch 2 on a yet to be confirmed release date. Deal of the Day
    0 Commentarios 0 Acciones