React Three Postprocessing - Bloom Looks Blocky - three.js

I am making a project using Next.js, Three.js, #react-three/fiber, and #react-three/postprocessing.
I wanted to create a Bloom effect, but it looks very weird and ugly. It doesn't inherit the mesh material emissive color - it is white, and it looks very blocky and pixelated.
The Noise effect is also weird. It looks OK, until I set the Blending Mode to Additive and then it looks glitchy when scrolling.
This is my code:
import { Canvas } from "#react-three/fiber";
import { Suspense } from "react";
import * as THREE from "three";
import gsap from "gsap";
import { Bloom, EffectComposer, Noise } from "#react-three/postprocessing";
const Three = () => {
return (
<Canvas>
<color attach="background" args={[0, 0, 0]} />
<Suspense fallback={null}>
<ambientLight />
<mesh position={[2, -3, 0]} scale={0.6}>
<sphereBufferGeometry attach="geometry" />
{/**#ts-ignore */}
<meshStandardMaterial
attach="material"
color="#571bff"
emissive="#571bff"
emissiveIntensity={200}
/>
</mesh>
</Suspense>
<EffectComposer>
<Bloom
luminanceThreshold={0}
luminanceSmoothing={0.9}
height={400}
opacity={3}
></Bloom>
<Noise opacity={0.01} blendFunction={THREE.AdditiveBlending} />
</EffectComposer>
</Canvas>
);
};
export default Three;
`
I would really appreciate any help because I really don't know how to fix this. Thank you very much.

Related

Html blurry on rotation: react-three/drei

So I can't seem to get html to rotate with react-three/drei without it being extremely blurry. It won't blur at smaller sizes, but whenever I add more text it reaches a point where it just blurs up like below.
If there's a more standard way to rotate an html container, please let me know and i'll just that because i'm losing my mind here.
Code:
<Html
as="div"
position={[0, 0, 0]}
rotation={[0, 0.4, 0]}
transform
style={{
backgroundColor: "green",
borderRadius: 4,
}}
>
<div>
{"Testingsss"}
</div>
...
</Html>
Without rotation:
With rotation:

React Native Images for Multiple Screens

I have an image which I want to display in top half of my screen. I'm using flux like this.
<View style={{flex:0.5}}>
<Image
style={{width:null, height:null, flex:1, resizeMode:'stretch'}}
source={require('../../../Images/salad-congo.png')}>
</Image>
</View>
<View style={{flex:0.5, backgroundColor:'yellow'}}>
<Text>Hello</Text>
</View>
Problem:
The problem is my image does not fit for all screen sizes. If I'm opening my app in landscape mode the image is centered instead of covering whole width and height of upper half. In case I use 'resizeMode='stretch'' my whole image is destroyed in pixels, and becomes un viewable. How can I make my image appear big for large screens, and small for small screens obviously covering the whole screen. Is there something I need to do with my image's resolutions? Or provide multiple images? If yes then how to handle them for both android and IOS
Import Dimensions From react native and then use it to set the size of your image
import {Dimensions} from 'react-native'
const SCREEN_WIDTH = Dimensions.get("window").width;
const logo = require("logo.png");
in the return of render:
<Image source={logo} style={styles.logo} />
const styles = StyleSheet.create({
logo: {
height: SCREEN_WIDTH * 0.65,
width: SCREEN_WIDTH * 0.65,
marginLeft: SCREEN_WIDTH * 0.2
}})
So I solved the issue by creating a single large image of 2056x2056, and then by using Flex properly to obtain the desired result. Tested the result on a couple of phones and tablets. Working Fine.
<View style={{flex:1}}>
<View style={{flex:0.6, alignItems:'stretch'}}>
<Image style={{flex:1, width: null, height: null }}
source={require('../../../Images/salad-congo2056x2056.png')}/>
</View>
<View style={{flex:0.1, backgroundColor:'#ffffff'}}>
// Intentional gap
</View>
<View style={{flex:0.3, backgroundColor:'red'}}>
// Anything here
</View>
</View>

How to dynamically scale an image in react-native?

I want an image to appear across the width of the screen, and be scaled so it retains its proportions.
I currently have this
<ScrollView style={styles.background}>
<Text>Some Header Text</Text>
<Image
style={{width: null}}
resizeMode="contain"
source={require("./assets/images/map.png")}
/>
</ScrollView>
which half works. The image is scaled correctly in width. but it is retaining its height, so there is a large border above and below the image.(ie the layout is still using the images height unscaled)
If I add a height: null or replace the width with a height then no image is displayed.
How do I do this (I expect) trivial thing?
(same behavior on ios and android.)
So I have had to calculate things myself.
This scales the image as I want, and the image is re-scaled when the phone is rotated.
I am not sure if componentWillMount is the right event to choose to calculate the width/height ratio. I would be happy for any other code review comments!
import React, {Component} from "react";
import {
StyleSheet,
Text,
View,
ScrollView,
Image,
Button,
Dimensions
} from "react-native";
import resolveAssetSource from "resolveAssetSource";
import {Actions} from "react-native-router-flux";
export default class Main extends Component {
measureView(event) {
this.setState({
width: event.nativeEvent.layout.width,
height: event.nativeEvent.layout.width
});
}
componentWillMount() {
let source = resolveAssetSource(require("./assets/images/map.png"));
this.setState({ratio: source.height / source.width});
}
render() {
return (
<ScrollView
onLayout={event => this.measureView(event)}
>
<Text style={styles.header}>
Some Header Text
</Text>
<Image
style={{
width: this.state.width,
height: this.state.width * this.state.ratio
}}
resizeMode="contain"
source={require("./assets/images/map.png")}
/>
</ScrollView>
);
}
}

How to animate elements inserted and removed in NativeScript's FlexboxLayout?

I'm trying to have a row of buttons that grow and shrink depending on if other buttons are added or removed. FlexboxLayout seems most appropriate for this job, but I can't seem to figure out how to approach the problem other than manually manipulating the width percentages over a time.
I thought I could set flexGrow on them and then use a class with visibility: collapse to essentially remove buttons. (And then reverse when returned to normal.) This works, but the change is pretty instantaneous. I would like some sort of squishing/stretching animation.
I tried playing with animations, shrinking the scale to 0 like below. Though the button appeared to shrink, it only did toward the center of itself and still held the space it took up (leaving a gap).
I'm playing with a simple example like this:
<FlexboxLayout flexDirection="row">
<Button text="1" width="25%" flexGrow="1"></Button>
<Button text="2" width="25%" id="test-button"></Button>
<Button text="3" width="25%" flexGrow="1"></Button>
<Button text="4" width="25%" flexGrow="1"></Button>
</FlexboxLayout>
And I tried doing something like this, where I want to shrink button #2 to gone:
let testButton = this.page.getViewById("test-button");
testButton.animate({
scale: { x: 0, y: 1},
duration: 500
});
I also tried to do it with keyframes. That seemed to not do anything.
#test-button {
animation-name: shrink;
animation-duration: 2s;
animation-delay: 1s;
}
#keyframes shrink {
from { width: 25%; }
to { width: 0; }
}
I tried to do something like what was mentioned in this answer here for web pages, but that also didn't seem to do anything.
I managed to get it to work by using databinding that manually adjusts the width using setTimeout. But I was wondering if there might be a different route that might be a bit easier to manage? Can't help but wonder if maybe I'm botching something in my other attempts.
You could hide the Button, while using button visibility property and to hide the component, when the animation finished. For your convenience I am attaching sample code
app.component.html
<FlexboxLayout flexDirection="row">
<Button backgroundColor="green" text="1" width="25%" flexGrow="1"></Button>
<Button backgroundColor="blue" (loaded)="buttonLoaded()" text="2" width="25%" id="test-button"></Button>
<Button backgroundColor="green" text="3" width="25%" flexGrow="1"></Button>
<Button backgroundColor="blue" text="4" width="25%" flexGrow="1"></Button>
</FlexboxLayout>
app.component.ts
import { Component } from "#angular/core";
import { Page } from "ui/page"
#Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent {
constructor(private page:Page){}
public buttonLoaded(){
let testButton = this.page.getViewById("test-button");
testButton.animate({
scale: { x: 0, y: 1},
duration: 500
})
.then(()=>{
let testButton = this.page.getViewById("test-button");
testButton.visibility='collapse'
});
}
}

NativeScript: how to make view 'transparent' for any user interactions

Is there a way to make a view 'transparent' to any user interactions? For example I have a view (with transparent background) and a button under that view. I want the user could tap the button under that view. If I have a scroller view under that view I want the user interacts with scroller when scroll over that view, so the view doesn't interfere or intercept user's gestures. But only this view should be transparent to user's interactions not its children. So, if I have a button inside that view it behaves normally.
Example XML:
<AbsoluteLayout width="100%" height="100%">
<Button text="Button1" tap="onTap1" />
<GridLayout width="100%" height="100%" backgroundColor="transparent">
<Button text="Button2" tap="onTap2" horizontalAlignment="center" verticalAlignment="center"/>
</GridLayout>
</AbsoluteLayout>
Thank you for your help.
You have multiple approaches to make a view change its color in NativeScript.
For example you can directly change its backgroundColor. Another oiption is to use animation and third option is to use CSS-animation.
Here is a basic example for the first two options.
page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<StackLayout>
<GridLayout width="300" height="300" id="myGrid" backgroundColor="transparent">
</GridLayout>
<Button text="Tap me" tap="onTap" />
<Button text="Or Tap me" tap="onAnotherTap" />
</StackLayout>
</Page>
page.js
import { EventData } from "data/observable";
import { Page } from "ui/page";
import { HelloWorldModel } from "./main-view-model";
import { GridLayout } from "ui/layouts/grid-layout";
import { Color } from "color";
var myGridView;
export function navigatingTo(args: EventData) {
var page = <Page>args.object;
page.bindingContext = new HelloWorldModel();
// get refference to the view using its id
myGridView = <GridLayout>page.getViewById("myGrid");
}
export function onTap(args:EventData) {
var color = new Color("#FF0000");
myGridView.backgroundColor = color;
}
export function onAnotherTap(args:EventData) {
myGridView.animate({
backgroundColor: new Color("#3D5AFE"),
duration: 3000
});
}
All of the options can be found described in NativeScript documenation

Resources